首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >链Scopes作为OR查询

链Scopes作为OR查询
EN

Stack Overflow用户
提问于 2016-07-16 09:59:17
回答 1查看 874关注 0票数 0

在模型中:

代码语言:javascript
复制
 scope :verified, -> { where(verified: true)}
 scope :active, -> { where(active: true) }

现在,Model.active.verified的结果是active and verified。如何将作用域链接为OR?请注意,我不想将这两个作用域合并为一个,例如:

where("active = ? OR verified = ?", true, true)

EN

回答 1

Stack Overflow用户

发布于 2016-07-16 12:25:48

您不必为了使用or而升级到Rails 5。在Rails 4中有一些方法可以做到这一点,虽然这些方法不能很好地用于链式作用域,但是在构建您的标准时可以达到类似的方便程度。

  1. 阿雷尔桌。Arel是ActiveRecord的关系代数的底层实现。它确实支持or以及其他强大的功能。 arel_table = Model.arel_table Model.where( arel_table:active.eq(真))。或( arel_table:verified.eq(true) )# =>从“模型”中选择“模型”.*(“模型”。“活动”=“t‘OR”模型。“验证”= 't')

如您所见,链接条件由于or必须在where中应用这一事实而变得复杂。在传递到where之前,可以从外部构建标准,但同样,它们的层次结构使它变得不那么简单。

  1. 对ActiveRecord进行猴子切换,添加or实现。把这个放进config/initializers/active_record.rb: ActiveRecord::QueryMethods::WhereChain.class_eval do def或(*作用域) scopes_where_values = [] scopes_bind_values = [] scopes_bind_values =[]在ActiveRecord::Relation scopes_where_values += scope.where_values scopes_bind_values += scope.bind_values时,Hash temp_scope =@scope.model.where(作用域) scopes_where_values+= temp_scope.where_values scopes_bind_values += temp_scope.bind_values end scopes_where_values =scopes_where_values.inject(:或) @scope.where_values += scopes_where_values @scope.bind_values += scopes_bind_values @scope end

有了这个,您就可以执行这样的or查询:

代码语言:javascript
复制
Model.where.or(verified: true, active: true)

# => SELECT "models".* FROM "models" WHERE ("models"."verified" = $1 OR "models"."active" = $2)  [["verified", "t"], ["active", "t"]]

您可以添加更多这样的条件:

代码语言:javascript
复制
Model.where.or(verified: true, active: true, other: false)

查询可以放在一个类方法中,如下所示:

代码语言:javascript
复制
def self.filtered(criteria)
  where.or(criteria)    # This is chainable!
end

或者在范围内,这基本上是一样的:

代码语言:javascript
复制
scope :filtered, lambda { |criteria| where.or(criteria) }

由于criteria只是一个散列,所以您可以使用任意多个元素方便地构建它:

代码语言:javascript
复制
criteria = {}
criteria[:verified] = true if include_verified?
criteria[:active] = true if include_active?
...

Model.filtered(criteria).where(... more criteria ...)

然后你就有了。要了解更多细节,请阅读以下问题:

ActiveRecord或条件

或Rails 4.2中带有Arel的WHERE子句中的运算符

最后,如果您不反对第三方解决方案,请查看尖叫声 gem。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38409943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档