2013-02-05 38 views
4

我有一個連接表連接的兩個車型:的Rails:操作中嵌套表格連接表

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「作者」和「翻譯者」創建了一對關聯。這些關聯在檢索相關數據方面效果很好,如@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 

這讓我覺得,我的唯一的辦法就是手動分配contributor_type在before_create回調,但如果是這樣的話,我怎麼決定分配哪些類型?參數的名稱中有正確的類型,例如:

publication[authors_attributes][0][name] 

有什麼方法可以訪問模型圖層中的信息嗎?

UPDATE:

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

你可以嘗試,而不是在窗體上添加一個隱藏字段? – jvnill

+0

我不確定這是否有幫助。 'contributor_type'屬性位於連接表中,不在Contributor模型中。由於我實際上並未在表單中聲明連接表,因此即使使用隱藏字段,我也無法訪問其屬性。但是,如果有一種方法可以在表單中創建連接表,那麼這種方法就可以工作。我會研究這個。如果您有任何其他建議,請告訴我。 – nullnullnull

+0

你是對的。如果你通過publication_contributor然後貢獻者,這是好的嗎? – jvnill

回答

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 %> 

UPDATE:控制器代碼

@publication.publication_contributors.build 
@publication.publication_contributors.each do |pc| 
    pc.build_contributor 
end 
+0

給了這個鏡頭,但我仍然得到構建錯誤。很奇怪,類似的情況在[RailsCast](http://railscasts.com/episodes/196-nested-model-form-part-1)上有效。 – nullnullnull

+0

我已經更新了我的答案,你的控制器應該至少看起來像什麼:) – jvnill

+0

當然!儘管我只創建了其中的一個,但publication_contributors仍然是一個關聯。有趣的是,我不能用'publication_contributors = @ publication.publication_contributors.build'來設置它,然後直接用'publication_contributors.each'來訪問它。不過,您的代碼完美無缺。那謝謝啦!這讓我感到困惑,我無法直接訪問publication_contributors。 – nullnullnull