1

我有一个模型“Collection”,它与其他 3 个模型具有 has_many_through 关系:“Song”、“Album”和“Artist”,通过连接表“Collectionitems”实现(fwiw collectionitem 是多态的,因此 has_many 声明中的 source 选项在下面的例子中。)

我想要完成的是确保放入连接表中的记录是唯一的(不同的),以便没有不必要的巨大表并且明显不处理重复项。

我的第一次尝试部分奏效了。

has_many :albums, -> { distinct }, through: :collectionitems, source: :collectable, source_type: "Album"
has_many :artists, -> { distinct }, through: :collectionitems, source: :collectable, source_type: "Artist"
has_many :songs, -> { distinct }, through: :collectionitems, source: :collectable, source_type: "Song"

这确实处理了 uniq 方面,但是如果我尝试添加集合中已经存在的内容,则会引发异常。

经过一番挖掘,我发现我可以创建一个块并<<像这样覆盖运算符:

has_many :albums, -> { distinct }, through: :collectionitems, source: :collectable, source_type: "Album"  do
  def <<(*items)
   super(items) rescue ActiveRecord::RecordInvalid
  end
end
has_many :artists, -> { distinct }, through: :collectionitems, source: :collectable, source_type: "Artist" do
  def <<(*items)
    super(items) rescue ActiveRecord::RecordInvalid
  end
end
has_many :songs, -> { distinct }, through: :collectionitems, source: :collectable, source_type: "Song" do
  def <<(*items)
    super(items) rescue ActiveRecord::RecordInvalid
  end
end

这让我更近了一步,因为现在异常已获救,并且记录很简单,如果它已经存在则不添加。

现在真正的问题:

假设我有一首歌曲的现有收藏项行:就像这样

Collection.first << Song.first

该歌曲已正确添加,因为它在集合中尚不存在。

现在,如果我尝试将 2 首或更多歌曲添加到同一个集合中并且其中一首歌曲已经存在(在本例中为歌曲 1),则添加失败。

Collection.first << Song.all

添加过程开始,但由于歌曲 1 已经存在,因此引发了异常,并且没有其他歌曲得到处理。

我想要的是让它简单地跳过第一首歌,因为它已经在收藏中了。有人可以在这里帮助我吗?

4

0 回答 0