0

在我的带有 Ruby 2 应用程序的 Rails 4 中,我有以下模型:

播放列表和曲目模型

APlaylist可以有许多Tracks 并且每个Track都有它position的s Playlist。对于每个新Track的,我想以position线程安全和/或多进程安全的方式将其设置为最后一个。

在我的研究中,我发现了一堆处理后台作业的项目,但我不希望这是后台,我希望它是同步的。所以我的 API 的调用者会得到正确的响应position

问题是:制作用于设置 aTrack在其位置的同步串行队列的最佳方法是什么Playlist

4

2 回答 2

1

正如其他人所建议的那样,如果您希望它是一个同步调用,只需将其添加到您的控制器操作中。只是有一个问题,是否要求您在 Track 模型中明确要求位置属性。因为默认情况下,您添加到播放列表的曲目会添加到末尾

playlist = Playlist.find params[:id]
playlist.transaction.do
  playlist.tracks.create(params[:track]) 
end

因此,当您想要添加的最后一首曲目时,您可以通过以下方式获取它

playlist.tracks.last

如果您想要对曲目进行某种排序,则可以向 Track 模型添加一些范围方法,以“按最新到最旧”或“按最旧到最新”呈现曲目(没有位置属性的示例)。

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

如果您想要对曲目进行某种排序,则可以向 Track 模型添加一些范围方法,以“按最新到最旧”或“按最旧到最新”呈现曲目(具有位置属性的示例)。

scope: sort_by_newest, order('position desc')
scope: sort_by_oldest, order('position asc')

希望能帮助到你。

于 2013-10-09T11:31:24.103 回答
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
于 2013-10-09T03:52:12.657 回答