在模型中:
scope :verified, -> { where(verified: true)}
scope :active, -> { where(active: true) }现在,Model.active.verified的结果是active and verified。如何将作用域链接为OR?请注意,我不想将这两个作用域合并为一个,例如:
where("active = ? OR verified = ?", true, true)
发布于 2016-07-16 12:25:48
您不必为了使用or而升级到Rails 5。在Rails 4中有一些方法可以做到这一点,虽然这些方法不能很好地用于链式作用域,但是在构建您的标准时可以达到类似的方便程度。
or以及其他强大的功能。
arel_table = Model.arel_table Model.where( arel_table:active.eq(真))。或( arel_table:verified.eq(true) )# =>从“模型”中选择“模型”.*(“模型”。“活动”=“t‘OR”模型。“验证”= 't')如您所见,链接条件由于or必须在where中应用这一事实而变得复杂。在传递到where之前,可以从外部构建标准,但同样,它们的层次结构使它变得不那么简单。
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查询:
Model.where.or(verified: true, active: true)
# => SELECT "models".* FROM "models" WHERE ("models"."verified" = $1 OR "models"."active" = $2) [["verified", "t"], ["active", "t"]]您可以添加更多这样的条件:
Model.where.or(verified: true, active: true, other: false)查询可以放在一个类方法中,如下所示:
def self.filtered(criteria)
where.or(criteria) # This is chainable!
end或者在范围内,这基本上是一样的:
scope :filtered, lambda { |criteria| where.or(criteria) }由于criteria只是一个散列,所以您可以使用任意多个元素方便地构建它:
criteria = {}
criteria[:verified] = true if include_verified?
criteria[:active] = true if include_active?
...
Model.filtered(criteria).where(... more criteria ...)然后你就有了。要了解更多细节,请阅读以下问题:
或Rails 4.2中带有Arel的WHERE子句中的运算符
最后,如果您不反对第三方解决方案,请查看尖叫声 gem。
https://stackoverflow.com/questions/38409943
复制相似问题