has_many:通过发布新记录

时间:2009-09-27 01:18:17

标签: ruby-on-rails associations

我根据我在this question的计划建模“特色”,并且遇到了一些绊脚石。

我正在定义一个Song的主要和特色艺术家:

  has_many :primary_artists, :through => :performances, :source => :artist,
           :conditions => "performances.role = 'primary'"

  has_many :featured_artists, :through => :performances, :source => :artist,
           :conditions => "performances.role = 'featured'"

这很好用,除非我正在创建一首新歌,而我通过primary_artist给它new_song.performances.build(:artist => some_artist, :role => 'primary')new_song.primary_artists不起作用(因为我创建的表演不是还没有保存在数据库中。

这里最好的方法是什么?我正在考虑使用类似的东西:

has_many :artists, :through => :performances

  def primary_artists
    performances.find_all{|p| p.role == 'primary'}.map(&:artist)
  end

3 个答案:

答案 0 :(得分:1)

我认为你过度复杂了。仅仅因为事情有相似之处并不意味着你应该把它们放在同一个盒子里。

class Song < ActiveRecord::Base

  has_one :artist  # This is your 'primary' artist
  has_and_belongs_to_many :featured_artists, :source => :artist  # And here you make a featured_artists_songs table for the simple HABTM join

  validates_presence_of :artist
end
噗,没有混乱。您仍然必须先添加song.artist才能保存,但这就是您想要的。正确?

答案 1 :(得分:0)

除非您保存,否则您无法识别关联。可以说,在您保存,验证通过以及相关交易完成之前,它确实不存在。

关于清理primary_artist方法的问题,您可以对此进行建模。

class Song < ActiveRecord::Base
  has_many :performances
  has_many :artists, :through => :performances
  has_one :primary_artist, :through => :performances, :conditions => ["performances.roll = ?", "primary"], :source => :artist
end

目前还不清楚您是否需要一位或多位主要艺术家,但您可以根据需要轻松将has_one切换为has_many

答案 2 :(得分:0)

您已经使用build vs. create确定了问题的根源。

至于寻找一首歌的主要艺术家。我会在艺术家上添加一个named_scope来选择特色/主要艺术家。

class Artist < ActiveRecord::Base
  ...
  named\_scope :primary, :joins => :performances, :conditions => "performances.role = primary"
  named\_scope :featured, :joins => :performances, :conditions => "performances.role = featured"
end

要获得一首歌的主要艺术家,你可以选择@ song.artists.primary或​​者你喜欢歌曲中的primary_artists方法。

def primary_artists
  artists.primary
end

但是,在查看了您的初始问题后,我认为您的数据库布局不足。这是可行的,但不清楚,I've posted my suggestions there, where it belongs.

这些命名的范围我也可以在我提出的方案下工作。