0

Rails 3.2.14 を使用していますが、初めて has_many :through を使用する際に問題が発生しました。デザイン イメージの順序ランキングを格納する Design_Pictures テーブルを使用して、Image テーブルと Design テーブルの間の has_many :through 関係を使用しています。すべての画像は 1 人のユーザーに関連付けられています。後で、特定のデザインに関連付けられていない他の画像を Images テーブルに格納する柔軟性が必要です。

サンプル データをデータベースに正常に追加し、ショー デザイン ページにイメージ タイトル (images テーブルに格納されている) とランキング (design_pictures テーブルに格納されている) を表示できます。私が理解できないのは、新しい design_picture を作成する方法です。これが機能するようになったら、CarrierWave または Paperclip を使用してイメージ テーブルにイメージを追加します。

ここに私のモデルがあります:

アプリ/モデル/image.rb:

class Image < ActiveRecord::Base
  attr_accessible :title
  belongs_to :user
  has_many :design_pictures, dependent: :destroy 
  has_many :designs, :through => :design_pictures

  validates :user_id, presence: true
  validates :title, length: { maximum: 80 }
end

アプリ/モデル/design.rb:

class Design < ActiveRecord::Base
  attr_accessible :title
  has_many :design_pictures, dependent: :destroy 
  has_many :images, :through => :design_pictures

  validates :title, presence: true, length: { maximum: 60 }
end

アプリ/モデル/design_picture.rb:

class DesignPicture < ActiveRecord::Base
  attr_accessible :ranking
  belongs_to :image
  belongs_to :design

  validates :image_id, presence: true
  validates :design_id, presence: true   

  default_scope order: 'design_pictures.ranking ASC'
end

アプリ/モデル/user.rb:

class User < ActiveRecord::Base
  attr_accessible :name
  has_many :designs, dependent: :destroy 
  has_many :images, dependent: :destroy

  validates :name, presence: true, length: { maximum: 50 }
end

ビュー:

アプリ/ビュー/デザイン/show.html.erb:

            <div>
                <% if @design.design_pictures.any? %>
                    <h3>Images (<%= @design.design_pictures.count %>)</h3>
                    <ul>
                        <%= render @design_pictures %>
                    </ul>
                <% end %>
            </div>

            <div>
                <%= render 'shared/design_picture_form' %>
            </div>

app/views/design_pictures/_design_picture.html.erb

<li>
    <%= design_picture.image.title %> - Ranking: <%= design_picture.ranking %>
</li>

app/views/shared/_design_picture_form.html.erb:

<%= form_for(@design_picture) do |f| %>
    <%= render 'shared/error_messages', object: f.object %>

    <%= f.label :title, "Title" %>
    <%= f.text_field :title, 
                placeholder: "Name your image.",
                class: "" %>

    <%= f.label :ranking, "Ranking" %>
    <%= f.text_field :ranking, 
            placeholder: "Rank your design picture.",
            class: "" %>            

    <%= hidden_field_tag(:design_id, @design.id) %>

    <%= f.submit "Add Image", class: "btn btn-large btn-primary" %>
<% end %>

コントローラー:

アプリ/コントローラー/designs_controller.rb

    def show
        @design = Design.find(params[:id])
        @design_pictures = @design.design_pictures.find(:all, :limit => 10)

        @image = current_user.images.build 
        @design_picture = @design.design_pictures.build
    end

アプリ/コントローラー/design_pictures_controller.rb

    def create
        @current_design = Design.find(params[:design_id])
        @image = current_user.images.new(params[:title])
        @design_picture = @current_design.design_pictures.build(:image_id => @image.id, params[:ranking])

        if @design_picture.save
            flash[:success] = "Micropost created!"
            redirect_to @current_design
        else
            redirect_to designs_url
        end
    end

design_picture フォーム パーシャルにアクセスするとエラーが発生します。

undefined method `title' for #<DesignPicture image_id: nil, design_id: 1427, ranking: nil>

フォームからタイトルを削除すると、フォームを送信できますが、何も作成されません。

どんな助けでも大歓迎です。

4

2 に答える 2

0

あなたには属性DesignPictureがありません。titleあなたがするとき:

@design.design_pictures.build

DesignPicture新しいインスタンスを構築します。そして、以下は機能しません:

<%= form_for(@design_picture) do |f| %>
  # ...

  <%= f.label :title, "Title" %>

  # ...

Nested Formをご覧ください。

于 2013-10-15T16:50:27.870 に答える
0

これが最善の方法かどうかはわかりませんが、フォームを送信して、タイトル属性を持つ Image エントリとランク属性を持つ Design_Picture エントリの両方を作成する方法です。私はaccepts_nested_attributes_forを使用する必要がなくなりました。

アプリ/ビュー/共有/_design_picture_form.html.erb

<%= form_for(@design_picture) do |f| %>
<%= render 'shared/error_messages', object: f.object %>

<%= label_tag(:title, "Title") %>
<%= text_field_tag(:title) %>   

<%= f.label :ranking, "Ranking" %>
<%= f.text_field :ranking, 
        placeholder: "Rank your design picture.",
        class: "" %>            

<%= hidden_field_tag(:design_id, @design.id) %>

<%= f.submit "Add Image", class: "btn btn-large btn-primary" %>

アプリ/コントローラー/designs_controller.rb

def show
    @design = Design.find(params[:id])
    @design_pictures = @design.design_pictures.find(:all, :limit => 10)

    @design_picture = @design.design_pictures.build
end

アプリ/コントローラー/design_pictures_controller.rb

def create
    @image = current_user.images.create(:title => params[:title])
    @current_design = Design.find(params[:design_id])       
    @design_picture = @current_design.design_pictures.build(params[:design_picture])
    @design_picture.image_id = @image.id

    if @design_picture.save
        flash[:success] = "Design Picture created!"
        redirect_to @current_design
    else
        redirect_to designs_url
    end
end
于 2013-10-18T23:28:17.577 に答える