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]モデルの 1 つでオーバーライドする必要があるメソッドを探しているようです。

ここで説明されています:accepts_nested_attributes_for with find_or_create? . この例は、単純な関連付け用has_manyです。

アソシエーションについては、has_many :through以下のコードのように sth を開発しました。

私のアプリでは、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 に答える