【问题标题】:Fetch ActiveRecord model for each key in array of hashes为哈希数组中的每个键获取 ActiveRecord 模型
【发布时间】:2021-05-21 18:11:17
【问题描述】:

我有一个带有评论 ID 和他的标题的哈希数组:

arr = [{comment_id: 1, title: 'Title 1'}, {comment_id: 5, title: 'Title 2'}]

对于每个哈希,我必须添加包含活动记录模型作为值的新 :key:

arr = [{comment_id: 1, user: #<User0x00007fd88dfe1b28>..., title: 'Title 1'},{comment_id: 5, user: #<User0x00005fd58dfe1a31>..., title: 'Title 2'}]

我找到的第一个解决方案是对每个哈希进行查询:

arr.each do |h|
 h[:user] = Comment.find(h[:comment_id]).user
end

但使用单个 sql-query 会更好 类似:

comment_ids = arr.map {|h| h[:comment_id] }
users = User.joins(:comments).order('comments.id').where(comments: {id: comment_ids })

# so here I need to match User with comment_id from comment_ids 

如果有人提出解决方案会很好。

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    首先,我会找到与评论 ID 相匹配的 cmets,还有 includes(:user)(参见 Rails eager loading guide),这样我们就可以在不需要额外查询的情况下让用户与评论相关联:

    comments = Comment.where(id: comment_ids).includes(:user)
    

    从这一点开始,您可以通过两种方式来处理事情。先Enumerable#find(和ActiveRecord::Base#find不同,顺便说一下)挑出特定id对应的评论,然后从该评论记录中读取用户

    arr.each do |h|
      comment = comments.find { |comment| comment.id == h[:comment_id] }
      h[:user] = comment.user
    end
    

    另一种方法是使用一些可枚举的操作来创建哈希,其中键是评论 ID,值是用户对象。见index_bytransform_values

    users_by_comment_id = comments.index_by(&:id).transform_values(&:user)
    
    arr.each do |h|
      h[:user] = users_by_comment_id[h[:comment_id]]
    end
    

    【讨论】:

      猜你喜欢
      • 2012-08-17
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-14
      • 2021-07-16
      相关资源
      最近更新 更多