我有两个通过连接表连接的模型:
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
请注意,连接表具有第三个属性(在publication_id和contributor_id旁边),称为contributor_type。此属性可能包含诸如“作者”,“翻译者”,“编辑者”或其他内容的角色。在我的出版物模型中,我为两个更常见的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
)上抛出此错误:
undefined method `build' for nil:NilClass
答案 0 :(得分: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