我有一个模型“Collection”,与其他3个模型有一个has_many_through关系:“Song”,“Album”和“Artist”,通过连接表“Collectionitems”实现(fwiw collectionitem是多态的,因此是源选项)以下示例中的has_many声明。)
我想要完成的是确保连接表中的记录是uniq(不同的),以便没有不必要的巨大表格而且明显不处理重复项。
我的第一次尝试部分起作用。
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方面但是如果我尝试添加已经存在于colelction中的东西,则会引发异常。
经过一番挖掘后,我发现我可以创建一个块并覆盖<<
运算符,如下所示:
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
这让我向前迈进了一步,因为现在异常被拯救了,如果记录已经存在,记录很简单。
现在真正的问题是:
说我有一首歌的现有collectionitem行:像这样
Collection.first << Song.first
该歌曲已正确添加,因为该歌曲尚未存在于该集合中。
现在,如果我尝试将2首或更多歌曲添加到同一集合中并且其中一首歌曲已经存在(在本例中为歌曲1),则添加失败。
Collection.first << Song.all
添加过程开始,但由于歌曲1已经存在,因此引发了异常,并且没有其他歌曲被处理。
我想要的是简单的跳过歌曲,因为它已经在收藏中了。有人可以帮我吗?