ruby Ordered与position属性有_many_though关联

twh00eeo  于 2023-10-18  发布在  Ruby
关注(0)|答案(2)|浏览(65)

我有两个型号PlaylistSong。播放列表具有通过具有position属性的连接表playlist_song_associations的歌曲的有序列表,例如

class Playlist < ApplicationRecord
  has_many :playlist_song_associations, dependent: :destroy
  has_many :songs, through: :playlist_song_associations
end

class Song < ApplicationRecord
  has_many :playlist_song_associations, dependent: :destroy
  has_many :playlists, through: :playlist_song_associations
end

class PlaylistSongAssociation < ApplicationRecord
  belongs_to :playlist, touch: true
  belongs_to :song
  default_scope { order(position: :asc) }
end

现在我有了一个更新控制器方法,在这里我做一些类似

playlist.songs = get_ordered_songs_from_params

我希望关联根据get_ordered_songs_from_params数组中的顺序进行排序。
有没有一种方法可以设置它,让rails自动在关联上设置position属性?

rmbxnbpk

rmbxnbpk1#

对于你是否可以让rails自动完成这个任务,答案也许是否定的,但也许这并不是你真正想要的?
按照您设置的方式,PlaylistSongAssociation是一个真实的对象。它的存在就像它有意义。但在播放列表之外,它真的没有任何意义。你永远不想独自编辑它。
一个更好的模型可能是在Playlist中有一个song_id数组,并删除PlaylistSongAssociation。缺点是,你几乎肯定会失去对歌曲的引用完整性-但这可能取决于你选择的数据库,也许这对你来说不是一个真实的问题(如果歌曲删除不太可能或非常罕见,或者你可以从中恢复)。
Add an array column in Rails
或者使用JSON列。这取决于你的数据库。

r7s23pms

r7s23pms2#

您可以在创建播放列表歌曲关联时使用回调自动填充“位置”字段。

before_save :ensure_position
def ensure_position
  self.position = playlist.songs.count + 1
end

如果您最近添加了对播放列表进行排序的可能性,并且之前没有“位置”字段,则需要使用migrationrake task使用数据填充此字段。您可以轻松填写该字段:

Playlist.all.each do |playlist|
  playlist.playlist_song_associations.each_with_index do |psa, i|
    psa.update(position: i + 1)
  end
end

这里的想法是自动位置设置时,它被添加到播放列表只有一次。如果你每次调用播放列表歌曲时都试图更新位置-你会破坏加载速度,并向数据库发送垃圾邮件请求。总是尽量只发出绝对必要的请求来保留资源,因为每一件小事都很重要。

相关问题