我有许多艺术家和艺术家可以在许多版本中出现的版本。可以通过嵌套属性在我的发布表单中创建艺术家。我遇到麻烦的是让find_or_create为艺术家工作。
我在我的模型中定义了以下代码,因为您可以在ArtistRelease模型中看到一个相当荒谬的get / set / delete例程来实现所需的结果。这确实有效,但我不喜欢它。我知道通过find_or_create有更好的方法。有人可以帮忙吗?我应该在哪里放置find_or_create才能使用?
class Release < ActiveRecord::Base
has_many :artist_releases, :dependent => :destroy
has_many :artists, :through => :artist_releases
accepts_nested_attributes_for :artists, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => :true
accepts_nested_attributes_for :artist_releases
end
class Artist < ActiveRecord::Base
has_many :artist_releases
has_many :releases, :through => :artist_releases
end
class ArtistRelease < ActiveRecord::Base
belongs_to :artist
belongs_to :release
before_create :set_artist_id
after_create :destroy_artist
default_scope :order => 'artist_releases.position ASC'
private
def set_artist_id
a = Artist.where("name =?", artist.name).reorder("created_at").find(:first)
a.role = artist.role
a.position = artist.position
a.save
artist_id = a.id
self.artist_id = artist_id
end
def destroy_artist
c = Artist.count(:all, :conditions => [ "name = ?", artist.name])
if c > 1
a = Artist.where("name =?", artist.name).reorder("created_at").find(:last)
a.destroy
end
end
end
答案 0 :(得分:2)
您似乎正在寻找应在其中一个模型中覆盖的autosave_associated_records_for_[model_name]
方法。
这里解释:accepts_nested_attributes_for with find_or_create?。这个例子是一个简单的has_many
关联。
我已经开发了has_many :through
关联,如下面的代码所示。
在我的应用中,我有一个order_item --< seat >-- client
连接。我正在使用新的order_item表单创建客户端。解决方案允许我创建一个新的客户端和一个座位关联,或者只有一个座位关联,当客户端表中已经有一个提供电子邮件的客户端时。它不会更新现有客户端的其他属性,但也可以轻松扩展它们。
class OrderItem < ActiveRecord::Base
attr_accessible :productable_id, :seats_attributes
has_many :seats, dependent: :destroy
has_many :clients, autosave: true, through: :seats
accepts_nested_attributes_for :seats, allow_destroy: true
end
class Client
attr_accessible :name, :phone_1
has_many :seats
has_many :order_items, through: :seats
end
class Seat < ActiveRecord::Base
attr_accessible :client_id, :order_item_id, :client_attributes
belongs_to :client, autosave: true
belongs_to :order_item
accepts_nested_attributes_for :client
def autosave_associated_records_for_client
if new_client = Client.find_by_email(client.email)
self.client = new_client
else
# not quite sure why I need the part before the if,
# but somehow the seat is losing its client_id value
self.client = client if self.client.save!
end
end
end
希望它有所帮助!