我有一个商店模型。
在我的课堂上,我创建了几种方法,使我能够更容易地阅读代码。
类似的事情:
# Returns True if the shop has an owner
def is_claimed
return self.owner_id != nil
end
现在我想创建一个返回商店集合的方法。
类似的东西:
def get_all_open
return Shop.where("shops.closed != 1")
end
我只是想知道应该放在哪里,所以我可以在任何可以使用的地方使用
Shop.all
在我的代码中。
我在互联网上看过,但到目前为止找不到我喜欢的东西。什么被认为是铁路的良好做法?
由于
答案 0 :(得分:3)
您可以将其保留在模型中,但不要将其定义为实例方法,而是将其定义为类方法:
def self.all_open
where("shops.closed != 1")
end
这样你可以像这样使用它:
Shop.all_open
甚至嵌套方法,如下:
Shop.all_open.where(field: "value")
<强>更新强>
与其他人指出的一样,您也可以使用范围(这是首选方式):
class Shop < ActiveRecord::Base
scope :all_open, -> { where("shops.closed != 1") }
end
用法是相同的:
Shop.all_open
答案 1 :(得分:2)
这是Scopes通常用于的目的。
class Shop < ActiveRecord::Base
scope :open, ->{ where("shops.closed != 1") }
# ->{ where.not(closed: true) } # <- Either will work, but I prefer this
# ...
end
然后:
Shop.open.all # => (a collection of Shops)
范围的优势在于您可以将它们链接起来,因此,例如,如果您的Shop模型具有type
属性,您可以获得具有特定type
的所有打开的商店,如下所示:< / p>
Shop.open.where(type: "pharmacy").all
答案 2 :(得分:0)
在Shop中将其定义为类方法。
class Shop
def self.all_open
where("shops.closed != 1")
end
end
open_shops = Shop.all_open
注意:
0)self
中的def self.all_open
使得这个类方法在类本身上定义,并且可以在类本身上调用为Shop.all_open
,而不是普通实例需要在特定实例上调用的方法。
1)当您致电all_open
时,调用方法get_all_open
而不是Shop.all_open
会产生更自然和惯用的代码。实际上,我可以将其称为open
,导致open_shops = Shop.open
。
2)注意建议的实现省略了return
,只是为了便于阅读。请注意,它也会忽略Shop.where
,而只会忽略where
。这主要是因为你最终制作商店的子类,你可能不会,但是风格好,代码更短。只有where
与self.where
相同,因为这是一个类方法,self
是类本身Shop
(除非您有继承此代码的子类,在这种情况下self
可以是一个子类)。
3)事实上你可以把它与东西连在一起,没问题。看看:Shop.all_open.where(:city => "Baltimore").order(:updated_at)
。非常整洁,它只是有效!
4)有些人会告诉你使用ActiveRecord'范围'。你真的不需要这种情况,你可以写一个简单的旧方法,就像那样。 Rails docs承认有关使用范围进行此类事情:“这与定义类方法完全相同,而您使用的是个人偏好问题。”我只是在这里使用一个简单的旧方法,就像你开始一样(除了在模型上定义为类方法) - 它更直接,它做你期望的,你不需要了解'范围',这只是一种方法。使用范围来代替这种方式是在Rails以这种方式使用普通类方法支持之前的一种遗留问题,普通的类方法就好了。