我注意到我的示波器的趋势,并试图弄清楚如何使其干燥
scope :newest, -> { order('created_at DESC') }
scope :top_sold, -> { order('qty_sold DESC') }
scope :most_viewed, -> { order('qty_viewed DESC') }
scope :most_downloaded, -> { order('qty_download DESC') }
scope :most_favorited, -> { order('qty_favorited DESC') }
我想传递我想要排序的列,以便我可以在Photo上调用它。我试过这个,但遇到了问题
scope :sort_photos, -> type { order('type DESC') }
Photo.sort_photos('qty_download')
我是在正确的道路上还是有更聪明的方法来实现这一目标?
答案 0 :(得分:1)
将type
作为范围参数传递,并在order
子句中使用字符串插值:
scope :sort_photos,->(type) { order("#{type} DESC") }
然后做:
Photo.sort_photos('qty_download')
答案 1 :(得分:1)
order
方法采用String或Hash。因此,您可以order('created_at DESC')
代替order(created_at: :desc)
,而不是type
。所以,要完成你想要的东西,就像将密钥更改为scope :sort_photos, -> type { order(type => :desc) }
变量一样简单:
order
我还建议您为by_
范围使用哨兵,例如by_sort_photos
。因此,范围sort_photos
不会被scope :newest, -> { by_most_recent_type('created_at') }
scope :top_sold, -> { by_most_recent_type('qty_sold') }
scope :by_most_recent_type, -> type { order(type => :desc) }
方法的定义或稍后的结果覆盖。
最后,拥有一个充满方法的公共接口,而不是需要知道类属性并将这些属性名称传递给公共接口方法,这样做是件好事。所以我保留了你拥有的许多不同的范围,但也许它们都引用了我们在这里定义的一般范围。所以:
{{1}}