在我使用Ruby 2应用程序的Rails 4中,我有以下模型:
Playlist
可以包含多个Track
个,Track
position
中有Playlist
个Track
。对于每个新的position
,我想以线程安全和/或多进程安全的方式将其position
设置为最后一个。
在我的研究中,我发现了一些处理后台工作的项目,但我不希望这是后台,我希望它是同步的。因此,我的API的调用者将获得具有正确Track
的响应。
问题是:制作同步串行队列的最佳方法是什么,该队列将用于设置Playlist
中{{1}}的位置?
答案 0 :(得分:1)
如果您希望它是同步的,那么您不需要队列。相反,您只需在事务中包含一些代码,在该事务中找到该播放列表的最后一个轨道位置,然后将新轨道的位置设置为一个,然后保存新轨道。这样的事情(假设你在控制器动作中):
@playlist = Playlist.find params[:id]
@track = Track.new params[:track]
@playlist.transaction do
last_track = @playlist.tracks.order("posistion desc").first
@track.position = last_track.position + 1
@track.save
end
答案 1 :(得分:1)
正如其他人所说,如果您希望它是同步调用,只需将其添加到您的控制器操作中。 只有一个问题,是否要求您在Track模型中明确要求position属性。因为默认情况下,您添加到播放列表的曲目会添加到结尾
playlist = Playlist.find params[:id]
playlist.transaction.do
playlist.tracks.create(params[:track])
end
因此,当您想要添加的最后一首曲目时,您可以通过
获取它playlist.tracks.last
如果您想为曲目进行某种排序,则可以在曲目模型中添加一些范围方法,以“按最新到最旧”或“按最旧到最新”(不带位置属性的示例)渲染曲目。 / p>
scope: sort_by_newest, order('created_at desc')
scope: sort_by_oldest, order('created_at asc')
如果您仍然需要使用position属性进行显式跟踪,那么
playlist = Playlist.find params[:id]
track_params = params[:track] || {}
track_params.merge!({position: playlist.tracks.count('id') + 1})
playlist.transaction.do
playlist.tracks.create(track_params)
end
如果您想为曲目进行某种排序,则可以在曲目模型中添加一些范围方法,以“按最新到最旧”或“按最旧到最新”(具有位置属性的示例)渲染曲目。 / p>
scope: sort_by_newest, order('position desc')
scope: sort_by_oldest, order('position asc')
希望它有所帮助。