根据所有者的父级

时间:2015-09-29 20:31:38

标签: ruby-on-rails validation activerecord model has-many-through

我的艺术家和专辑模型之间有has_many through关联设置。要添加一张专辑has_many曲目。曲目在艺术家之间也有has_many through关联(即特色艺术家),其中Feature模型用作连接表。

我想阻止专辑艺术家成为赛道上的精选艺术家。例如:

album = Album.find_by(name: "Justified")
track = Album.track.first
artist = Artist.find_by(name: "Justin Timberlake")

track.featured_artists << artist 

# ^^ Should raise error since Justin Timberlake is the album's artist

模型设置

class Album < ActiveRecord::Base
  has_many :album_artists
  has_many :artists, through: :album_artists
end

class Track < ActiveRecord::Base
  belongs_to :album

  has_many :features
  has_many :featured_artists, through: :features, class_name: "Artist", foreign_key: "artist_id"
end

class AlbumArtist < ActiveRecord::Base
  belongs_to :album
  belongs_to :artist

  validates_uniqueness_of :artist_id, scope: :album_id
end

class Feature < ActiveRecord::Base
  belongs_to :track
  belongs_to :featured_artist, class_name: "Artist", foreign_key: "artist_id"
end

class Artist < ActiveRecord::Base
  has_many :album_artists
  has_many :albums, through: :album_artists

  has_many :features
  has_many :tracks, through: :features
end

有没有办法使用其中一种开箱即用的验证方法来实现这一目标?如果不是,如果没有向专辑的所有者写一个可笑的长查找链,我将如何创建一个自定义验证器,假设验证器在Feature模型中?

1 个答案:

答案 0 :(得分:0)

您可以测试两个艺术家数组的交集(&amp;)是否为空。

class Track < ActiveRecord::Base
  belongs_to :album

  has_many :features
  has_many :featured_artists, through: :features, class_name: "Artist", foreign_key: "artist_id"

  validate :featured_artists_cannot_include_album_artists

  def featured_artists_cannot_include_album_artists
    if (album.artists & featured_artists).present?
      errors.add(:featured_artists, "can't include album artists")
    end
  end
end