我的类中有一个方法,它接受一个数字参数。它看起来像这样:
def with_at_least_x_posts(min_posts)
self.where("posts_counter >= ?", min_posts)
end
我想创建一个方法,将该参数放在其名称中,而不是括号中,所以不要调用
User.with_at_least_x_posts(10)
我可以打电话
User.with_at_least_10_posts
这需要通过某种正则表达式机制来定义该方法。我知道find_by
方法是这样工作的(即find_by_some_column
),所以它应该是可能的吗?
有人可以通过告诉我如何在Ruby 1.9.2和Rails 3.1中实现这一点而不需要深入研究Rails核心并为自己找到它来节省一些时间吗?
谢谢!
更新:在等待答案时,我一直在挖掘Rails核心。似乎它们覆盖了ActiveRecord::Base中的method_missing
方法,并将自定义方法的处理委托给名为DynamicFinderMatch的模块。有趣的东西!
能够像Ruby一样在Ruby中定义方法真的很棒:
def /with_at_least_[0-9]+_posts/
x = $0
end
但我想现在不太可能。有趣的东西!
答案 0 :(得分:3)
您应该在常规Ruby方法method_missing
def with_at_least_x_posts(min_posts)
self.where("posts_counter >= ?", min_posts)
end
def method_missing(sym, *args, &block)
begin
if sym.to_s =~ /with_at_least_(\d+)_posts/
return send :with_at_least_x_posts, *(args.push($1.to_i)), &block
end
rescue NoMethodError => e
raise "Unable to find method: #{e.inspect}"
end
return super
end
从这里开始,您就可以致电myObj.with_at_least_10_posts
。搏一搏!您可以阅读更多here。
P.S。这在Ruby中很常见(这是ActiveRecord所做的)。请注意,如果您收到StackOverflow错误,那是因为method_missing
中引发的method_missing
错误将导致无限递归。要小心!
答案 1 :(得分:2)
您可以使用method_missing
执行此操作,但这是一种危险的方法,可能会导致代码非常混乱。相反,怎么样
User.with_more_posts_than(10)
更干净(更容易使用和维护)。它仍然可以正确读取。
作为众多异议中的一个特定点,您不应将10
转换为字符串并返回。这带来了一大堆新的潜在错误,您将在稍后处理这些错误。