Ruby Rails 个范围包含 OR
Ruby on Rails scopes containing OR
在 ActiveRecord 模型的作用域中使用 OR 在链接这些作用域时会导致一些奇怪的行为。假设我们有两个要分离检查的条件,并且还希望检查发生的范围是可链接的。给定具有以下范围的模型:
class Test < ActiveRecord::Base
scope :test1, lambda { where(SOME_CONDITION).or(SOME_OTHER_CONDITION) }
scope :test2, lambda { where(id: Test.where(SOME_CONDITION).or(SOME_OTHER_CONDITION)) }
end
然后他们之间有一个微妙的区别。前者在调用时表现正确:Test.test1
,但如果在 test1
之前调用任何其他范围,则 or
会导致一些意外行为,因为先前的范围现在只能与 SOME_CONDITION。使用 test2
修复了这个问题,但生成了一个看起来非常 hacky 的查询,即使对于简单的情况 Test.test2
也是如此。此外,后者看起来非常 hacky。有没有推荐的方法来解决这个问题?
由于替代方案可能是尝试确定条件是否已经存在(例如 where
已经被调用),这甚至比在我看来子查询,你最好的选择可能是使用 Arel
来创建条件。
class Test < ActiveRecord::Base
scope :test, -> (val1,val2) {
where(
arel_table[:column].in(val1).or(
arel_table[:column2].in(val2)
)
)
}
end
当将范围链接在一起时,此选项将与顺序无关
在 ActiveRecord 模型的作用域中使用 OR 在链接这些作用域时会导致一些奇怪的行为。假设我们有两个要分离检查的条件,并且还希望检查发生的范围是可链接的。给定具有以下范围的模型:
class Test < ActiveRecord::Base
scope :test1, lambda { where(SOME_CONDITION).or(SOME_OTHER_CONDITION) }
scope :test2, lambda { where(id: Test.where(SOME_CONDITION).or(SOME_OTHER_CONDITION)) }
end
然后他们之间有一个微妙的区别。前者在调用时表现正确:Test.test1
,但如果在 test1
之前调用任何其他范围,则 or
会导致一些意外行为,因为先前的范围现在只能与 SOME_CONDITION。使用 test2
修复了这个问题,但生成了一个看起来非常 hacky 的查询,即使对于简单的情况 Test.test2
也是如此。此外,后者看起来非常 hacky。有没有推荐的方法来解决这个问题?
由于替代方案可能是尝试确定条件是否已经存在(例如 where
已经被调用),这甚至比在我看来子查询,你最好的选择可能是使用 Arel
来创建条件。
class Test < ActiveRecord::Base
scope :test, -> (val1,val2) {
where(
arel_table[:column].in(val1).or(
arel_table[:column2].in(val2)
)
)
}
end
当将范围链接在一起时,此选项将与顺序无关