散列/数组到活动记录 [英] Hash/Array to Active Record

查看:188
本文介绍了散列/数组到活动记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  @record = @ record.sort_by {| rec | 
如果user.fav_record.find(rec.id)
User.fav_record(rec.id).created_at
else
rec.created_at
End

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

问题:
这个函数返回一个数组而不是一个活动记录类。

我尝试了一切以获得这个返回一个活动记录类。我已经将已排序的元素推送到一个ID数组中,并尝试按照该顺序提取它们,我尝试了映射。我得到的每个结果都将我以前的活动记录转换为数组或散列。现在我需要它回到活跃的记录。有没有人知道如何将活动记录的数组或哈希值转换回活动记录类?

解决方案

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

如果要优化应用程序的性能,应该尽量避免将数组转换为ActiveRecord查询。尝试并尽可能长时间保持对象为查询。



这就是说,使用数组通常比查询更容易,并且它可能感觉像是一个麻烦对ActiveRecord查询(SQL)代码进行大量数组操作。



使用 sort 代码会更好。 rubyonrails.org/active_record_querying.htmlrel =nofollow> ActiveRecord :: Query方法,甚至使用 find_by_sql 写入普通SQL。



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

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



下面是一个避免N + 1 SQL问题的数组实现的例子:

 #首先将所有用户的收藏加载到内存
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)}
#这是使用Array#查找,而不是ActiveRecord方法
如果matching_rec
matching_rec.created_at
else
rec.created_at
end
end

这个实现和代码在你的问题是,我避免每次迭代循环调用ActiveRecord的 find 。 SQL读/写在计算上花费很大,并且你希望你的代码尽可能少。

I have been searching everywhere but I can't seem to find this problem anywhere. In Rails 5.0.0.beta3 I need to sort a my @record = user.records with an association and it's record. The sort goes something like this.

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

This is just an example of what I do. But everything sorts fine.

The problem: This returns an array and not an Active Record Class.

I've tried everything to get this to return an Active Record Class. I've pushed the sorted elements into an ID array and tried to extract it them in that order, I've tried mapping. Every result that I get turns my previous active record into an array or hash. Now I need it to go back into an active record. Does anyone know how to convert an array or hash of that active record back into an Active Record class?

解决方案

There isn't a similarly easy way to convert ActiveRecord to array.

If you want to optimize the performance of your app, you should try to avoid converting arrays to ActiveRecord queries. Try and keep the object as a query as long as possible.

That being said, working with arrays is generally easier than queries, and it can feel like a hassle to convert a lot of array operations to ActiveRecord query (SQL) code.

It'd be better to write the sort code using ActiveRecord::Query methods or even writing it in plain SQL using find_by_sql.

I don't know what code you should specifically use here, but I do see that your code could be refactored to be clearer. First of all, If and Else should not be capitalized, but I'm assuming that this is just pseudocode and you already realize this. Second, your variable names should be pluralized if they are queries or arrays (i.e. @record.sort_by should be @records.sort_by instead).

It's worth mentioning that ActiveRecord queries are difficult to master and a lot of people just use array operations instead since they're easier to write. If "premature optimization is the root of all evil", it's really not the end of the world if you sacrifice a bit of performance and just keep your array implementation if you're just trying to make an initial prototype. Just make sure that you're not making "n+1" SQL calls, i.e. do not make a database call every iteration of your loop.

Here's an example of an array implementation which avoids the N+1 SQL issue:

# 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

The main difference between this implementation and the code in your question is that I'm avoiding calling ActiveRecord's find each iteration of the loop. SQL read/writes are computationally expensive, and you want your code to make as little of them as possible.

这篇关于散列/数组到活动记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆