我有一个方法
class Student < ActiveRecord::Base
def self.search(options = {})
all.tap do |s|
s.where(first_name: options[:query]) if options[:query]
s.where(graduated: options[:graduated]) if options[:graduated]
# etc there are many more things that can be filtered on...
end
end
end
当调用这个方法时,我得到的是所有的结果,而不是我期望的过滤集。似乎我的tap
功能没有像我期望的那样工作。正确的方法是什么(不将all
赋值给变量)?如果可能的话,我想在这里使用块)。
3条答案
按热度按时间nxagd54h1#
tap
对此不起作用。all
是一个ActiveRecord::Relation
,一个等待发生的查询。all.where(...)
返回 newActiveRecord::Relation
新查询。all
),而不是块的返回值。也就是说,它是这样定义的:
当你想要的只是:
或者类似的东西。
这就是为什么你总是得到 * 所有 * 返回的对象,而不是查询得到的对象。我的建议是建立发送给
where
的散列,而不是链接where
调用。就像这样:或者一个更好的实现:
(If中间变量不符合您的口味。)
fivyi3re2#
您可以轻松创建
let
函数:然后这样使用:
tap
和let
的区别在于tap
返回对象,而let
返回块的返回值。4ngedf3f3#
现在(ruby >= 2.5)你可以使用
Object.yield_self
: