【问题标题】:Hash/Array to Active Record哈希/数组到活动记录
【发布时间】:2016-08-18 06:37:38
【问题描述】:

我一直在到处搜索,但似乎在任何地方都找不到这个问题。在 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 类。

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

【问题讨论】:

  • 您所说的 ActiveRecord 类是指一个关系(您可以调用诸如 where 之类的方法)吗?
  • 是的。抱歉,我不在电脑旁,所以我根据记忆提出了这个问题。但我不能做一个 where 子句。
  • 我已经有记录了。那时我需要进行排序。并转换回活动记录关系。这甚至可能吗?
  • @FelixRamirez 使用 order 而不是 sort merhods

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


【解决方案1】:

没有类似的简单方法可以将 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 读/写在计算上是昂贵的,并且您希望您的代码尽可能少地使用它们。

【讨论】:

  • 非常感谢您的解释和代码示例。是的,我写的代码只是伪代码。我在我的 Android 设备上写了这篇文章,所以大写和复数单词只是拼写错误。如此说来。如果问题得到解决,我将尝试您分享的示例并更新帖子。再次感谢。
  • 嗯,我测试了算法。虽然效率更高。我仍然有同样的问题。 @records 排序后不再是活动记录。它只是一个数组,因此导致我的视​​图崩溃。因此,我将尝试将我们与算法一起使用的确切模式写入 SQL 语句。但再次感谢您的意见。非常感谢。
  • @FelixRamirez MVC 的主要概念之一是避免将数据库逻辑放在视图中。因此,我建议重构您的视图,使其不依赖于您的查询对象。顺便说一句,有一些方法可以使用find 并保留对象的顺序。有关更多信息,请参阅here。有人在这个问题上发布了this gem,这似乎很有用。
猜你喜欢
  • 1970-01-01
  • 2017-12-10
  • 2020-07-13
  • 2018-04-28
  • 2019-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
相关资源
最近更新 更多