清洁方式找到ActiveRecord对象,由id指定的顺序顺序、清洁、对象、方式

2023-09-09 21:58:56 作者:似水流年

我想获得的ActiveRecord对象的数组给定一组ID。

I want to obtain an array of ActiveRecord objects given an array of ids.

我认为

Object.find([5,2,3])

将返回一个数组对象5,目标2,则该订单对象3,而是我得到一个数组有序的对象2,对象3,然后物体5。

Would return an array with object 5, object 2, then object 3 in that order, but instead I get an array ordered as object 2, object 3 and then object 5.

ActiveRecord的基础找到方法API 提到,你不应该指望它在订单提供(其他文件不给这个警告)。

The ActiveRecord Base find method API mentions that you shouldn't expect it in the order provided (other documentation doesn't give this warning).

的一个潜在的溶液中查找,但该命令选项似乎没有有效的SQLite的。

One potential solution was given in Find by array of ids in the same order?, but the order option doesn't seem to be valid for SQLite.

我可以写一些红宝石code的对象我自己(或者有点简单,缩放不佳或更好的缩放和更复杂的)排序,但有没有更好的办法?

I can write some ruby code to sort the objects myself (either somewhat simple and poorly scaling or better scaling and more complex), but is there A Better Way?

推荐答案

这并不是说MySQL和自己其他的DB类的东西,那就是他们没有对它们进行排序。当你调用 Model.find([5,2,3]),生成的SQL是这样的:

It's not that MySQL and other DBs sort things on their own, it's that they don't sort them. When you call Model.find([5, 2, 3]), the SQL generated is something like:

SELECT * FROM models WHERE models.id IN (5, 2, 3)

这不指定命令,只是一套要返回的记录。事实证明,一般MySQL将返回'身份证'序数据库中的行,但不能保证这一点。

This doesn't specify an order, just the set of records you want returned. It turns out that generally MySQL will return the database rows in 'id' order, but there's no guarantee of this.

要得到数据库返回的记录在保证秩序的唯一方法是添加订单条款。如果你的记录将始终以特定顺序返回,那么你可以添加一个排序列到数据库并做 Model.find([5,2,3]:为了=>'sort_column )。如果不是这种情况,你必须做排序在code:

The only way to get the database to return records in a guaranteed order is to add an order clause. If your records will always be returned in a particular order, then you can add a sort column to the db and do Model.find([5, 2, 3], :order => 'sort_column'). If this isn't the case, you'll have to do the sorting in code:

ids = [5, 2, 3]
records = Model.find(ids)
sorted_records = ids.collect {|id| records.detect {|x| x.id == id}}