Ruby on rails 在Rails中保存关联记录的顺序有很多:通过关联
我正在开发一个Rails插件,它包括一种通过关联修改has_many:中关联记录顺序的方法。假设我们有以下型号:Ruby on rails 在Rails中保存关联记录的顺序有很多:通过关联,ruby-on-rails,activerecord,associations,ruby-on-rails-plugins,has-many-through,Ruby On Rails,Activerecord,Associations,Ruby On Rails Plugins,Has Many Through,我正在开发一个Rails插件,它包括一种通过关联修改has_many:中关联记录顺序的方法。假设我们有以下型号: class Playlist < ActiveRecord::Base has_many :playlists_songs, :dependent => :destroy has_many :songs, :through => :playlists_songs end class Song < ActiveRecord::Base has_ma
class Playlist < ActiveRecord::Base
has_many :playlists_songs, :dependent => :destroy
has_many :songs, :through => :playlists_songs
end
class Song < ActiveRecord::Base
has_many :playlists_songs, :dependent => :destroy
has_many :playlists, :through => :playlists_songs
end
class PlaylistsSong < ActiveRecord::Base
belongs_to :playlist
belongs_to :song
end
class Playlist:销毁
有许多:歌曲,:至=>:播放列表\u歌曲
结束
类歌曲:销毁
有许多:播放列表,:至=>:播放列表\u歌曲
结束
类playlysong
如果我们更改播放列表中歌曲的顺序(例如,@Playlist.Songs.rotate!
),Rails不会触及playlists\u Songs表中的记录(我使用的是Rails 3.1),这是有意义的。我想调用Playlist的songs=method保存歌曲的顺序,也许可以通过删除playlists\u歌曲中的相关现有行并按正确的顺序创建新行(以便在检索它们时可以使用:order=>“id”
)或者在歌曲播放列表中添加sort:integer列,并相应地更新这些值
我没有看到任何回调(例如,在添加之前)允许这样做。实际上,相关的方法似乎是,而且,但我不知道下一步最好的方法是什么。有没有一种方法可以扩展或安全地覆盖这些方法中的一种,以实现我正在寻找的功能(最好只针对特定的关联),或者有没有其他更好的方法来实现这一点?您看过吗?它是最古老的rails插件之一,旨在处理此类问题
它不是按id
排序,而是按位置列排序。然后,这仅仅是更新位置的问题,而不是更改id
或删除/替换记录的麻烦事
在您的情况下,只需将位置
整数列添加到播放歌曲
,然后:
class PlayListSong
acts_as_list :scope => :play_list_id
end
正如您在评论中指出的那样,中的方法充当列表
主要作用于列表中的单个项目,并且没有现成的“重新排序”功能。我不建议篡改replace_记录
来执行此操作。使用与插件相同的position列编写方法会更简洁、更明确。比如说
class PlayList
# It makes sense for these methods to be on the association. You might make it
# work for #songs instead (as in your question), but the join table is what's
# keeping the position.
has_many :play_list_songs, ... do
# I'm not sure what rotate! should do, so...
# This first method makes use of acts_as_list's functionality
#
# This should take the last song and move it to the first, incrementing
# the position of all other songs, effectively rotating the list forward
# by 1 song.
def rotate!
last.move_to_top unless empty?
end
# this, on the other hand, would reorder given an array of play_list_songs.
#
# Note: this is a rough (untested) idea and could/should be reworked for
# efficiency and safety.
def reorder!(reordered_songs)
position = 0
reordered_songs.each do |song|
position += 1
# Note: update_column is 3.1+, but I'm assuming you're using it, since
# that was the source you linked to in your question
find(song.id).update_column(:position, position)
end
end
end
end
这里有一位老铁路司机介绍了acts_as_的名单:谢谢你的提示;我以前看过acts_as_列表,现在我只是尝试一下。不幸的是,它无法解决加入模型的记录在
@playlist.songs.rotate期间未被更新的问题不过,代码>。如果从@playlist.Songs添加或删除歌曲,位置会更新,但如果仅更改歌曲的顺序,则不会更改任何内容。这是在playlassong中定义的acts\u as\u list:scope=>:playlist\u id
中。如果我遗漏了另一个选项,请让我知道,但我在acts_as_的来源列表中没有看到任何与上述问题相关的内容。其他想法?谢谢你的想法;不幸的是,在仍然使用CollectionAssociation::writer
的情况下,没有办法保持顺序,但这样可能更安全。这似乎是一个重新排序
-style方法可能是下一个最好的解决方案,但如果其他人稍后看到这一点并对此有其他想法,请随时与我们分享。