是否有可能否定Rails 3中的范围?

我的类名为Collection我有以下范围:

 scope :with_missing_coins, joins(:coins).where("coins.is_missing = ?", true) 

我可以运行Collection.with_missing_coins.count并得到一个结果 – 它很棒! 目前,如果我想获得不丢失硬币的collections品,我会添加另一个范围:

 scope :without_missing_coins, joins(:coins).where("coins.is_missing = ?", false) 

我发现自己写了很多这些“相反”的范围。 是否有可能在不牺牲可读性或求助于lambda /方法(将truefalse作为参数)的情况下获得范围的反面?

像这样的东西:

 Collection.!with_missing_coins 

我不会为此使用单个范围,而是两个:

 scope :with_missing_coins, joins(:coins).where("coins.is_missing = ?", true) scope :without_missing_coins, joins(:coins).where("coins.is_missing = ?", false) 

这样,当使用这些范围时,它就会明确地发生了什么。 有了这些数字1311407的建议,还不能立即清楚with_missing_coinsfalse参数是做什么的。

我们应该尝试尽可能清楚地编写代码,如果这意味着不再是关于DRY的狂热者,那么就这样吧。

在Rails 4.2中,您可以:

 scope :original, -> { ... original scope definition ... } scope :not_original, -> { where.not(id: original) } 

它将使用子查询。

虽然我不认为使用lambda方法是一个问题,但是范围本身并没有“逆转”。

 scope :missing_coins, lambda {|status| joins(:coins).where("coins.is_missing = ?", status) } # you could still implement your other scopes, but using the first scope :with_missing_coins, lambda { missing_coins(true) } scope :without_missing_coins, lambda { missing_coins(false) } 

然后:

 Collection.with_missing_coins Collection.without_missing_coins