散列/数组到活动记录

时间:2016-04-25 01:52:31

标签: ruby-on-rails arrays ruby activerecord hash

我一直在寻找,但我似乎无法在任何地方找到这个问题。在Rails 5.0.0.beta3中,我需要使用关联及其记录对我的@record = user.records进行排序。 排序就是这样的。

@record = @record.sort_by { |rec| 
If user.fav_record.find(rec.id)
  User.fav_record(rec.id).created_at
Else 
  rec.created_at
End

这只是我所做的一个例子。但一切都很好。

问题: 这将返回一个数组而不是Active Record Class。

我已经尝试了一切来让它返回一个Active Record Class。我已经将已排序的元素推入ID数组并尝试按顺序提取它们,我已经尝试过映射。我获得的每个结果都将我之前的活动记录转换为数组或哈希。现在我需要它回到活跃的记录。有谁知道如何将该活动记录的数组或散列转换回Active Record类?

1 个答案:

答案 0 :(得分:2)

将ActiveRecord转换为数组没有类似的简单方法。

如果要优化应用的性能,应尽量避免将数组转换为ActiveRecord查询。尽可能尝试将对象保留为查询。

话虽这么说,使用数组通常比查询更容易,并且将大量数组操作转换为ActiveRecord查询(SQL)代码会感觉很麻烦。

最好使用ActiveRecord::Query methods编写sort代码,或者使用find_by_sql在纯SQL中编写代码。

我不知道你应该在这里专门使用什么代码,但我确实看到你的代码可以重构为更清晰。首先,IfElse不应该大写,但我假设这只是伪代码,你已经意识到这一点。其次,如果变量名称是查询或数组,则它们应该是多元的(即@record.sort_by应该是@records.sort_by)。

值得一提的是,ActiveRecord查询很难掌握,很多人只是使用数组操作,因为它们更容易编写。如果“过早优化是所有邪恶的根源”,那么如果你牺牲一点性能并且只是在你试图制作初始原型时保持阵列实现,那么它真的不是世界末日。只要确保你没有进行“n + 1”SQL调用,即在循环的每次迭代中调用数据库。

这是一个避免N + 1 SQL问题的数组实现示例:

# first load all the user's favorites into memory
user_fav_records = user.fav_records.select(:id, :created_at)
@records = @records.sort_by do |record|
  matching_rec = user.fav_records.find { |x| x.id.eql?(rec.id) }
  # This is using Array#find, not the ActiveRecord method
  if matching_rec
    matching_rec.created_at
  else 
    rec.created_at
  end
end

这个实现和你的问题中的代码之间的主要区别在于我在循环的每次迭代中都避免调用ActiveRecord的find。 SQL读/写的计算成本很高,并且您希望代码尽可能少地创建。