0

我有可以有很多艺术家的版本,并且艺术家可以出现在许多版本中。艺术家可以通过嵌套属性在我的发布表单中创建。我遇到的问题是让 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
4

1 回答 1

1

您似乎正在寻找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

希望能帮助到你!

于 2012-11-25T19:01:11.677 回答