2016-12-22 108 views
6

我有完全相同的模式與多態連接表說明如下:http://aaronvb.com/articles/a-polymorphic-join-table.html一次創建多個多態性記錄軌道

class Location < ActiveRecord::Base 
    has_many :note_joins, as: :notable 
    has_many :notes, through: :note_joins 
end 

class Checkpoint < ActiveRecord::Base 
    has_many :note_joins, as: :notable 
    has_many :notes, through: :note_joins 
end 

class NoteJoin < ActiveRecord::Base 
    belongs_to :notable, polymorphic: true 
    belongs_to :note 
end 

class Note < ActiveRecord::Base 
    attr_accessible :content, :user_id 
    belongs_to :notable, polymorphic: true 
    belongs_to :user 

    has_many :note_joins 
end 

我希望能夠創建和更新多種類型的多態關聯的同時,而不必做@note.locations << Location.first@note.checkpoints << Checkpoint.first

類似@note.create note_joins_params@note.update note_joins_params會很棒。

到目前爲止,我已經能夠實現創建部分的方式是將一組屬性傳遞給@note.note_joins.create,例如, :

note_joins_params = [{"notable_id"=>"9225", "notable_type"=>"Location"}, {"notable_id"=>"9220", "notable_type"=>"Checkpoint"}] 
@note.note_joins.create note_joins_params 

是否有更多的Rails式的方式來做到這一點,或適當的屬性哈希語法類似於accepts_nested_attributes或類似的東西?

也只有這樣,我知道怎麼做的update是先刪除所有的連接表,然後重新創建這些現有的記錄,即

@note.note_joins.destroy_all 
new_note_joins_params = [{"notable_id"=>"9225", "notable_type"=>"Location"}, {"notable_id"=>"9220", "notable_type"=>"Checkpoint"}] 
@note.note_joins.create new_note_joins_params 
+0

Rails的不具備accept_nested_attribute多態協會的大力支持。也許你應該檢查這個線程http://stackoverflow.com/q/3969025/4587148 – Sajan

回答

6

對於要完成的任務,如果您沒有指定source_type,Rails實際上並沒有接受嵌套屬性的'smart_way'。請參閱本The other side of polymorphic :through associations

不過你可以試試這個:

class Location < ActiveRecord::Base 
    has_many :note_joins, as: :notable 
    has_many :notes, through: :note_joins 

    accepts_nested_attributes_for :notes 
end 

class Checkpoint < ActiveRecord::Base 
    has_many :note_joins, as: :notable 
    has_many :notes, through: :note_joins 

    accepts_nested_attributes_for :notes 
end 

class NoteJoin < ActiveRecord::Base 
    belongs_to :notable, polymorphic: true 
    belongs_to :note 

    accepts_nested_attribute_for :note 
end 

class Note < ActiveRecord::Base 
    attr_accessible :content, :user_id 
    belongs_to :user 

    has_many :note_joins 
    # add these, otherwise you won't be able to do nested attributes 
    # refer to the blog post I link above. 
    has_many :locations, through: :note_joins, source: :notable, source_type: 'Location' 
    has_many :checkpoints, through: :note_joins, source: :notable, source_type: 'Checkpoint' 
end 

然後在你的形式,建立這樣的事情:

# In your form 

# if you want to create from the note, do this 
<%= form_for @note do |f| %> 
    <%= f.text_field :some_note_field %> 
    <%= text_field_tag 'note[locations_attributes][][some_location_field]' %> 
    <%= text_field_tag 'note[checkpoints_attributes][]some_checkpoint_field]' %> 
<% end %> 

# if you want to create from the location/checkpoint, do this. 
<%= form_for @location do |f| %> 
    <%= f.text_field :name %> 
    <%= text_field_tag 'location[notes_attributes][][body]' %> 
<% end %> 


# In your Location/Checkpoint controllers 

def create 
    @location = Location.create(location_params) 
    redirect_to @location 
end 

def location_params 
    params.required(:location).permit(:name, notes_attributes: [:body]) 
end 

# In your Note controller 
def create 
    @note = Note.create(note_params) 
    redirect_to @note 
end 

def note_params 
    # the goal here is to create a set of params like this 
    # { note_field: 'foobar', 
    # locations_attributes: [{name: 'somewhere'}], 
    # checkpoints_attributes: [{description: 'lol'}] } 
    params.required(:note).permit(:note_field, locations_attributes: [:location_field], checkpoints_attributes: [:checkpoint_field]) 
end 
+0

這不會回答我問的問題。我想創建不只是一個位置,但一次創建不同類型的多態模型。 – jsurf

+0

@jsurf你一次是什麼意思?你的意思是在同一時間創建'註釋'以及'位置','檢查點'? –

+0

我誤解了我的問題。我最初有一個STI設置,它可以很容易地創建一個由不同類型的繼承模型組成的列表,因爲我只需要從一個表中引用ID。現在我已經切換到多態關聯,現在我有ID和類型。我想創建一個由位置和檢查點組成的列表。所以我正在使用ID和類型數組添加到連接表中: '''params = [{「notable_id」=>「9225」,「notable_type」=>「Location」},{「notable_id」 =>「9220」,「notable_type」=>「檢查點」}] ''' '@note.note_joins.create params' – jsurf