ruby-on-rails – 在Rails 4.2中使用Arel的WHERE子句中的OR运算符

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 在Rails 4.2中使用Arel的WHERE子句中的OR运算符前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下代码在Rails 4.1中构造了一个带有OR运算符的有效where子句
  1. MyModel.where(
  2. MyModel.where(attribute1: 1,attribute2: 2).where_values.reduce(:or)
  3. )

这大致相当于sql

  1. select * from my_models where (attribute1 = 1 OR attribute2 = 2)

在Rails 4.2中,相同的代码生成一个SQL查询,其缺少值的绑定参数

  1. select * from my_models where attribute1 = OR attribute2 =

…并且由于缺少绑定值的值而生成错误.

Rails 4.2中用OR运算符生成有效查询的等效代码是什么?

编辑:

解决方案需要使用Arel :: Nodes :: Node派生对象,以便它本身可以通过AND和OR分组与其他条件组合.

  1. rel = MyModel.where(attribute1: 1,attribute2: 2)
  2. conditions = [rel.where_values.reduce(:or).to_sql,*rel.bind_values.map(&:last)]
  3.  
  4. MyModel.where(conditions)

条件var必须是Arel :: Nodes :: Node的衍生物.上述解决方案适用于简单查询,但对于更复杂的查询,条件必须是要传递给最终查询方法的Arel节点.

解决方法

我正在使用下面的东西,直到导轨5出来(在导轨5 AR支持.or):
  1. ActiveRecord::QueryMethods::WhereChain.class_eval do
  2. def or(*scopes)
  3. scopes_where_values = []
  4. scopes_bind_values = []
  5. scopes.each do |scope|
  6. case scope
  7. when ActiveRecord::Relation
  8. scopes_where_values += scope.where_values
  9. scopes_bind_values += scope.bind_values
  10. when Hash
  11. temp_scope = @scope.model.where(scope)
  12. scopes_where_values += temp_scope.where_values
  13. scopes_bind_values += temp_scope.bind_values
  14. end
  15. end
  16. scopes_where_values = scopes_where_values.inject(:or)
  17. @scope.where_values += [scopes_where_values]
  18. @scope.bind_values += scopes_bind_values
  19. @scope
  20. end
  21. end

有了以上你可以做到:

  1. MyModel.where.or(attribute1: 1,attribute2: 2)
  2. # or
  3. MyModel.where.or(MyModel.where(some conditions),MyModel.where(some other conditions))

猜你在找的Ruby相关文章