当我有一些id,比如
ids = [2,3,5]
Run Code Online (Sandbox Code Playgroud)
我表演
Comment.find(ids)
Run Code Online (Sandbox Code Playgroud)
一切正常.但是当存在不存在的id时,我会得到一个例外.当我获得与某些过滤器匹配的ID列表时,通常会发生这种情况
current_user.comments.find(ids)
Run Code Online (Sandbox Code Playgroud)
这次我可能有一个有效的评论ID,但不属于给定的用户,所以找不到它,我得到一个例外.
我试过了find(:all, ids),但它返回了所有记录.
我现在能做到的唯一方法是
current_user.comments.select { |c| ids.include?(c.id) }
Run Code Online (Sandbox Code Playgroud)
但在我看来,这似乎是超低效的解决方案.
有没有更好的方法在Array中选择ID而不会在不存在的记录上获得异常?
当你Something.find(array_of_ids)在Rails中,所得到的数组的顺序不依赖的顺序array_of_ids.
有没有办法找到并保存订单?
ATM我根据ID的顺序手动对记录进行排序,但这有点蹩脚.
UPD:如果可以使用:orderparam和某种SQL子句指定顺序,那么如何?
到目前为止,从数据库获取随机记录的"常见"方法是:
# Postgress
Model.order("RANDOM()").first
# MySQL
Model.order("RAND()").first
Run Code Online (Sandbox Code Playgroud)
但是,在Rails 5.2中执行此操作时,它会显示以下Deprecation警告:
DEPRECATION WARNING:使用非属性参数调用的危险查询方法(其参数用作原始SQL的方法):"RANDOM()".Rails 6.0中不允许使用非属性参数.不应使用用户提供的值调用此方法,例如请求参数或模型属性.可以通过将它们包装在Arel.sql()中来传递已知安全值.
我对Arel并不熟悉,所以我不确定解决这个问题的正确方法是什么.
ruby-on-rails rails-activerecord deprecation-warning ruby-on-rails-5.2
我正在考虑解决问题的最佳方案.假设我们有一个ActiveRecord模型的ID列表:
ids = [1, 100, 5, 30, 4, 2, 88, 44]
Run Code Online (Sandbox Code Playgroud)
然后我想进行查询,选择所有用户,例如列表中的ID,但保持订单.如果我做
User.where(id: ids)
Run Code Online (Sandbox Code Playgroud)
响应将是具有asc order by id的用户列表,但我希望订单与数组中的顺序相同.
您认为这是最好的解决方案吗?选择所有用户,然后操作ActiveRecord对象列表?也许有一种更聪明的方法可以做到这一点.
谢谢!
我有一组id,存储在一些外部存储(rails cache或redis)中.在控制器的操作中,我获取此数据并使用它选择对象,即
ids = [5, 1, 17, 84] # really fetched from external source
result = MyModel.where(:id => ids)
Run Code Online (Sandbox Code Playgroud)
我也希望它的顺序与array_of id中的id相同:
ids == result.map(&:id) # => true
Run Code Online (Sandbox Code Playgroud)
作为解决方法,我使用mysql FIELD函数排序:
MyModel.where(:id => ids).order("FIELD(id, #{ids.join ', '})")
Run Code Online (Sandbox Code Playgroud)
但我不喜欢这种方法,因为它是特定于mysql的,并且在大ids数组的情况下创建非常长的查询.有没有更好的,与DB无关的方法呢?从数据库获取未分类的数据并在ruby端进行排序是不可取的,因为它资源昂贵并且难以与分页一起使用.
谢谢.
使用硬编码数组
array = [30,29,31,13,10,12,6,7,8,9,11]
Run Code Online (Sandbox Code Playgroud)
尝试执行查询
@pick = Item.where('id IN (?)', array).to_a
Run Code Online (Sandbox Code Playgroud)
选择的 Items 的顺序如何保持初始数组的顺序?