4

結合テーブルで接続された2つのモデルがあります。

class Publication < ActiveRecord::Base
  attr_accessible :title, :author_attributes, :translator_attributes

  has_many :publication_contributors
  has_many :authors, :through => :publication_contributors, :source => :contributor,
    :conditions => {:publication_contributors => {:contributor_type => "Author"}}
  has_many :translators, :through => :publication_contributors, :source => :contributor,
    :conditions => {:publication_contributors => {:contributor_type => "Translator"}}

  accepts_nested_attributes_for :authors, :translators
end

class Contributor < ActiveRecord::Base
  attr_accessible :name

  has_many :publications, :through => :publication_contributors
  has_many :publication_contributors
end

class PublicationContributor < ActiveRecord::Base
  attr_accessible :contributor_type

  belongs_to :publication
  belongs_to :contributor
end

結合テーブルには、contributor_typeと呼ばれる3番目の属性(publication_idとcontributor_idの横)があることに注意してください。この属性には、「作成者」、「翻訳者」、「編集者」などの役割が含まれる場合があります。私のパブリケーションモデルでは、2つのより一般的なcontributor_types、「Author」と「Translator」の関連付けのペアを作成しました。これらの関連付けは、などの関連データを取得する際にうまく機能し@publication.authorsます。ただし、ネストされたフォームを介してこれらの関連付けを作成すると、飛び散ります。

私のフォームは次のようになります。

<%= form_for @publication, :remote => true do |f| %>

  <%= f.label :title %>:
  <%= f.text_field :title %>

  <%= f.fields_for :authors do |builder| %>
    <%= builder.label :name, "Author" %>:
    <%= builder.text_field :name %>
  <% end %>

  <%= f.fields_for :translators do |builder| %>
    <%= builder.label :name, "Translator" %>:
    <%= builder.text_field :name %>
  <% end %>

  <%= f.submit %>
<% end %>

私のコントローラーでは:

def create
  publication = Publication.create(params[:publication])
end

フォームは期待どおりにレンダリングされますが、作成アクション中にスパッタされます。Railsが、次のようなパブリケーションアソシエーションの条件に基づいて適切なcontributor_typeを魔法のように割り当てることを知っていることを望んでいました。

has_many :authors, :through => :publication_contributors, :source => :contributor,
:conditions => {:publication_contributors => {:contributor_type => "Author"}}

残念ながら、そうではありません。作成中にこのエラーが発生します:

Mysql2::Error: Column 'contributor_type' cannot be null

これは、私の唯一の頼みの綱はbefore_createコールバックでcontributor_typeを手動で割り当てることだと思いますが、その場合、どのタイプを割り当てるかをどのように決定しますか?パラメータの名前には、次のような適切なタイプがあります。

publication[authors_attributes][0][name]

モデルレイヤーでその情報にアクセスする方法はありますか?

アップデート:

私のnew行動:

def new
  @publication = Publication.new
  publication_contributor = @publication.publication_contributors.build
  contributor = publication_contributor.contributor.build
end

contributor最後の行(1つの設定)にこのエラーがスローされます。

undefined method `build' for nil:NilClass
4

1 に答える 1

6

次のことを試してみてください。

class Publication < ActiveRecord::Base
  attr_accessible :title, :publication_contributors_attributes

  has_many :publication_contributors
  has_many :authors, through: :publication_contributors, source: :contributor, conditions: { publication_contributors: { contributor_type: 'Author' } }
  has_many :translators, through: :publication_contributors, source: :contributor, conditions: { publication_contributors: { contributor_type: 'Translator' } }

  accepts_nested_attributes_for :publication_contributors
end

class Contributor < ActiveRecord::Base
  attr_accessible :name

  has_many :publications, through: :publication_contributors
  has_many :publication_contributors
end

class PublicationContributor < ActiveRecord::Base
  attr_accessible :contributor_type

  belongs_to :publication
  belongs_to :contributor

  accepts_nested_attributes_for :contributor
end

<%= form_for @publication, :remote => true do |f| %>

  <%= f.label :title %>:
  <%= f.text_field :title %>

  <%= f.fields_for :publication_contributors do |pc_form| %>
    <%= pc_form.hidden_field :contributor_type %>
    <%= pc_form.fields_for :contributor do |c_form| %>
      <%= c_form.label :name, "Author" %>:
      <%= c_form.text_field :name %>
    <% end %>
  <% end %>

  <%= f.submit %>
<% end %>

更新:コントローラーコード

@publication.publication_contributors.build
@publication.publication_contributors.each do |pc|
  pc.build_contributor
end
于 2013-02-05T04:26:11.830 に答える