6

Tôi có schema chính xác giống như mô tả ở đây với một bảng tham gia đa hình: http://aaronvb.com/articles/a-polymorphic-join-table.htmlTạo nhiều bản ghi đa hình cùng một lúc ray

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 

Tôi muốn để có thể tạo và cập nhật nhiều loại hiệp hội đa hình cùng một lúc, thay vì phải làm @note.locations << Location.first hoặc @note.checkpoints << Checkpoint.first.

Thứ gì đó như @note.create note_joins_params@note.update note_joins_params sẽ thật tuyệt vời.

Cách tôi đã có thể đạt được phần sáng tạo cho đến nay là bằng cách chuyển một loạt các thuộc tính đến @note.note_joins.create, ví dụ: :

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

Có cách nào khác để thực hiện điều này hoặc cú pháp băm thuộc tính thích hợp tương tự như accept_nested_attributes hoặc tương tự?

Cũng cách duy nhất tôi biết làm thế nào để làm một update là trước hết phải xóa tất cả các bản ghi hiện có trong bảng tham gia và sau đó tái tạo chúng, tức là

@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 không có hỗ trợ cho accept_nested_attribute cho hiệp hội đa hình. Có lẽ bạn nên kiểm tra chủ đề này http://stackoverflow.com/q/3969025/4587148 – Sajan

Trả lời

6

Đối với những gì bạn muốn đạt được, Rails không thực sự có 'smart_way' này khi chấp nhận thuộc tính lồng nhau nếu bạn không chỉ định source_type. Tham khảo này The other side of polymorphic :through associations

Nhưng bạn có thể thử điều này:

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 

Sau đó, trong hình thức của bạn, xây dựng một cái gì đó như thế này:

# 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

điều này không trả lời câu hỏi tôi đã hỏi .. Tôi muốn tạo không chỉ một Địa điểm, mà còn là các loại mô hình đa hình khác nhau cùng một lúc . – jsurf

+0

@jsurf ý bạn là gì? bạn có nghĩa là tạo một 'note' cùng với' location', 'checkpoint' cùng một lúc không? –

+0

Tôi đã nói sai câu hỏi của mình. Ban đầu tôi có một thiết lập STI ở đó dễ dàng tạo danh sách được tạo thành từ các kiểu mô hình kế thừa khác nhau cùng một lúc, vì tôi chỉ cần tham chiếu ID từ một bảng. Bây giờ tôi đã chuyển sang các hiệp hội đa hình, bây giờ tôi có ID và loại. Tôi muốn tạo danh sách gồm cả Địa điểm và Điểm kiểm tra cùng một lúc. Vì vậy, những gì tôi đang làm là thêm vào bảng tham gia bằng cách sử dụng mảng ID và loại: '' 'params = [{" notable_id "=>" 9225 "," notable_type "=>" Location "}, {" notable_id " => "9220", "notable_type" => "Điểm kiểm tra"}] '' ' '@note.note_joins.create params' – jsurf

Các vấn đề liên quan