Ruby on Rails:如何"check-out"模型值



我是这方面的新手,所以请原谅我缺乏术语和经验。

如果你不想阅读下面的全部解释,这里是我想做的事情的简短部分:

  • 我的网站上的用户对彼此的歌曲进行反馈
  • 两个用户不应该同时对同一首歌给出反馈

所以,我想建立一种"签出"系统,让用户签出一首歌并给予反馈。因此,如果一个用户签出了一首歌,另一个用户将无法访问它。此外,如果签出歌曲的用户留下反馈,歌曲将返回到未签出状态。如果用户没有留下反馈并离开页面,歌曲将返回到未选中状态。

这是短版本,这是长版本:

我有一个网站,我希望人们在那里交换对彼此歌曲的反馈,但他们只能收到他们给出的反馈。为了做到这一点,我有一个页面,我称之为"饲料"。

当有人访问此页面时,他们会看到一首歌,并收到一张表格以留下反馈。如果他们留下反馈,他们会为自己的歌曲获得一个反馈。

我在控制器中这样做:

@track = Track.where.not(user_id: current_user.id).
where.not(id: current_user.feeds.select(:track_id)).
where("tracks.feed_avaliable > '0'").
where("pref_genre = #{current_user.genre_id} OR genre_wait <= ?", ((Time.now.to_i - Track.last.last_feed.to_i) / 3600)).
reorder(feed_level: :asc, last_feed: :desc, created_at: :asc).
first()

这有望找到第一首曲目/歌曲,其中曲目的用户不是当前用户,其中当前用户之前没有留下反馈,其中可用的反馈>0,其中有曲目首选流派是当前用户流派,或者流派等待时间大于自上一次反馈以来的时间。按馈送级别从最小到最大、最后一次馈送时间从最长到最快、创建时间从最早到最快的顺序对轨迹进行排序。

无论如何,现在我陷入了一个问题,如果两个人最终在同一时间在同一条赛道上给出反馈,会怎么样。

这就是为什么我想要一些轨道的"检出"方法。因此,如果一个用户当前正在对某首曲目进行反馈,则另一个用户将不会从上述公式中获得该曲目的服务。

有人能帮忙吗?

您可以在Song模型上创建一个布尔字段,称为"checked_out"。创建一个控制器方法来检查歌曲,或者在检查歌曲的任何控制器方法中包含设置checked_out字段的代码。创建布尔字段后,Rails将生成一个方法checked_out?,您可以使用该方法来确定歌曲是否已检出,以及是否允许其他用户检出。

...
@song = Song.find(params[:id])
unless @song.checked_out?
@song.update_attribute :checked_out, true
end
...

你需要注意的是,你不允许用户永远签出歌曲——如果一个用户签出了一首歌,然后离开了,再也没有回来,你会希望有一个在某个时候重新签入的过程。

如果在你进行的过程中,你发现自己在歌曲的签出状态周围添加了很多布尔字段,这可能表明状态机是一个合适的解决方案。

在模型文件中为Song创建一个范围以获取未检出的歌曲也会很有帮助:

scope :not_checked_out, -> { where checked_out: false }

如果您只想显示未签出的歌曲,请使用此选项-当然,如果页面呈现后某首歌曲被另一用户签出,您仍然希望签入控制器。

最新更新