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