2011-07-26 64 views
2

我们正在更新导轨2应用程序。我们很高兴地使用了fake_arel,它提供了一个非常好的'或'范围。导轨3 - '或'示波器

现在,与轨3我无法找到一种方法来复制这一点。

我们有这样的代码:

scope.or(Event.horse, Event.dog, Event.trap).today 

这个模型看起来是这样的:

class Event < ActiveRecord::Base 
named_scope :horse, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_horse_ids] }} 
named_scope :dog, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_dog_ids] }} 
named_scope :trap, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_trap_ids] }} 
end 

这些示波器必须是独立的,并用于所有的地方。这个模型实际上有几十个组合使用的范围,所以重写它们是我们想要做的最后一件事。

看起来很奇怪,你不能'或'范围在一起。

有人可以提出一种方法来做到这一点在Rails 3中很好吗?即使使用arel我也看不到如何。 我们在不同的项目中使用meta_where,但它也不提供任何这样的事情。

回答

1

好了,做到这一点的方法是,在你的模型(它适应您的需求!):

where(:event => ['horse', 'dog', 'trap']) 

阵列会产生报表,这是你想要那里。此外,您还可以使用轨道3级范围来实现这一目标:

scope :my_scope, where(:event => ['horse', 'dog', 'trap']) 

然后你就可以使用这种方式:

mymodel.my_scope # and possibility to chain, like : 
mymodel.my_scope.where(:public => true) 
+0

也许我不明白在哪里把这个。如果我把它放在我的事件模型上(像这样:scope:find_scope,where(:event => ['horse','dog','trap']))我得到:ActiveRecord :: StatementInvalid:没有名为'event '存在表'事件' – phil

+0

这就是为什么我写道:适应您的需求!如果你在这里发布你的模型,我会帮你弄明白。 –

+0

我已更新模型。我看不出你在做什么以任何方式调用现有的范围,这是整个问题。 – phil

0

我撕掉了从fake_arel的“或”功能,并得到了它与轨工作3.0倍(不知道它会与3.1工作,因为我们不使用这里)

我的情况下任何人有兴趣我已经把它放在一个gist

0

我无法得到来自Phil的Github-gist的代码工作,但它激励我提出以下内容,我认为这是一个更简单的解决方案。它使用了一个返回ActiveRecord :: Relation类的类方法。

def self.or alt_scope 
    either = scoped.where_clauses.join(' AND ') 
    alternative = alt_scope.where_clauses.join(' AND ') 

    Locatie.unscoped.where("(#{either}) OR (#{alternative})"). 
    joins(scoped.joins_values).joins(alt_scope.joins_values). 
    group(scoped.group_values).group(alt_scope.group_values). 
    having(scoped.having_values).having(alt_scope.having_values). 
    includes(scoped.includes_values).includes(alt_scope.includes_values). 
    order(scoped.order_values).order(alt_scope.order_values). 
    select(scoped.select_values).select(alt_scope.select_values) 
end 

只需将其添加到您的班级。然后你会得到创建多个或查询的功能如下:

Event.horse.or(Event.dog).or(Event.trap) 

,你可以因此“存储”的范围:

scope :horse_dog_or_trap, horse.or(Event.dog).or(Event.trap) 

甚至还可以进一步扩大范围,这样作为:

Event.horse.or(Event.dog).or(Event.trap).today