繁体   English   中英

Ruby on Rails-用于关联和created_at的group_by

[英]Ruby on Rails - group_by for relation and created_at

我正在寻找一个Rails查询,该查询将为我获取当前用户制作的每部电影的最新创建评分。

例如,假设我有这个活动记录集合:

#<ActiveRecord::Relation [
  #<Rating id: 115, score: 5, movie_id: 7, user_id: 5, created_at: "2019-09-16 16:47:55", updated_at: "2019-09-16 16:47:55">,
  #<Rating id: 116, score: 3, movie_id: 7, user_id: 5, created_at: "2019-09-16 16:47:57", updated_at: "2019-09-16 16:47:57">,
  #<Rating id: 117, score: 5, movie_id: 7, user_id: 5, created_at: "2019-09-16 16:50:37", updated_at: "2019-09-16 16:50:37">,
  #<Rating id: 118, score: 3, movie_id: 8, user_id: 5, created_at: "2019-09-16 16:50:42", updated_at: "2019-09-16 16:50:42">
]>

我们可以看到存在三个带有movie_id7对象,一个带有movie_id6 这是错误的,因为我需要从current_user获取每部电影的最新评级。

例如,仅此行:

Rating.order(created_at: :desc).select('DISTINCT ON (movie_id) *')

我的模型关联:

class Movie < ApplicationRecord
  belongs_to :user
  has_many   :ratings, dependent: :destroy
end

class Rating < ApplicationRecord
  belongs_to :user
  belongs_to :movie
end

class User < ApplicationRecord
  has_many :movies
  has_many :ratings
end

请解释一下Rails查询,因为我真的很想理解这一点。

让我们分批完成!

您需要一个Rails查询,该查询将为我获取当前用户制作的每部电影的最新创建评分。

好的,有了这些信息,让我们从current_user参考开始!

您与User关系如下:

user有很多movies

user有很多ratings

使用这些定义,您可以利用ActiveRecord运行以下方法:

current_user.movies # All movies of a current_user
current_user.movies # All ratings of a current_user

好的,现在我们可以访问用户实例中的所有电影和分级,但是如何访问按电影分组的分级?

让我们看一下Rating关系:

rating属于user #,这表示该等级实例具有user_id

rating属于movie #,这表示该评级实例具有movie_id

真好! 现在,我们可以movie将用户评级分组

current_user.ratings.group_by { |rating| rating.movie_id }
# or the sugar sintax
grouped_ratings = current_user.ratings.group_by(&:movie_id)

这将根据movie_id对所有用户评分进行movie_id ,并向我们产生一个哈希值,例如:

{
  1: [#<Rating id: 115...#>, #<Rating id: 116...#>], # The "1" means the movie_id of the group_by
  2: [#<Rating id: 117...#>] # The "2" means the movie_id of the group_by
}

好的,现在我们得到了来自user的评分的哈希值,并按movie_id分组。

但是,我们需要用户为每部电影正确创建的最新评级吗?

last_ratings_for_each_movie = grouped_ratings.map do |movie_id, ratings|
  movie = Movie.find(movie_id)
  last_rating = ratings.sort_by{ |rating| rating.created_at }.last

  puts "The last Rating created by the current user for Movie #{movie.title} is the rating #{last_rating.id}" # Assuming movie has a title

  last_rating
end

在最后一刻,您将拥有为电影创建的最后一个评分的数组(例如,要访问电影,您可以执行一个rating.movie

我不知道您是否必须使用SQL进行操作,如果可以,请告诉我:)

希望能帮助到你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM