2013-02-07 37 views
1

我已经定义了一个模型中的两个范围样的方法:红宝石自我的方法链

def self.foo var 
    where(foo: var) 
end 

def self.bar var 
    where(bar: var) 
end 

我希望能够通过零到这些方法中的一个,并把它有效地忽略。所以:

var1 = 10 
var2 = nil 
# ... 
Model.foo(var1).bar(var2) 

我已经尝试了各种东西,如:

def self.bar var 
    return self if var.nil? 
    where(bar: var) 
end 

但在上述情况下,self不返回什么这种方法已经从以前的方法链中获得通过,它返回Model,因此我失去了在foo中完成的所有工作。

我怎样才能达到我想要的?

+0

你尝试像'所有()'如果它是零?我不知道这是否可行。我也不是这种模式的粉丝;我认为这是误导。 –

+0

我尝试过'all',但是它返回一个数组,所以如果我有另一个范围,我会得到'未定义的方法',例如'for#

回答

1

相信在轨3.x中,你应该能够使用这样的事情:

return self.scoped if var.nil? 

在轨4.x中,您需要更改到:

return self.all if var.nil? 

基本上,'scoped'(以及在rails 4中的所有')返回一个关系对象,您可以将其与其他arel方法链接起来,而无需实际应用任何条件。

+0

'self.scoped',以及我从来没有..谢谢@sockmonk!知道必须有这样的东西。 –

1

all实际上运行查询和回访的ActiveRelation对象,它是被用来延迟加载只是当它实际上需要返回结果的查询(例如:当你真正运行each)。否则,它根本不会执行查询,从而保存您对数据库的调用。它也允许你基本上试图在这里实现的好链接。

你可能想尝试什么是

def self.bar(val) 
    return where({}) if val.nil? 
    where(:bar => val) 
end 
+0

这个工程!没有任何东西传到'where'。 –