Rails 4:将复杂的过滤器转换为范围

时间:2016-10-18 20:48:26

标签: ruby-on-rails scope many-to-many has-many-through

在将我的食谱模型连接到我的标签模型时,我有一个多对多/多对多的关系,以便:

class Tag < ActiveRecord::Base
    has_many :taggings
    has_many :recipes, through: :taggings
end

class Tagging < ActiveRecord::Base
  belongs_to :tag
  belongs_to :recipe
end

class Recipe < ActiveRecord::Base
    has_many :taggings
    has_many :tags, through: :taggings
end

...有没有办法通过范围过滤具有相同标签的食谱?我是范围新手,但我发现它们比方法更有用,我只能通过方法实现标记名称的搜索和过滤。

例如,这将为我提供标有给定名称的所有食谱:

def self.tagged_with(name)
    Tag.find_by_name!(name).recipes
end

1 个答案:

答案 0 :(得分:-1)

您基本上可以将大多数关联方法链(尽管不是全部*)转换为范围

例如,我试试这个(注意:没有测试过bug),看看结果如何

scope :tagged_with, ->(name) { find_by_name!(name).recipes }

如果这不起作用,我会尝试类似:

scope :tagged_with, ->(name) { where(:name => name).first.recipes }

[*]使用范围超过方法链接的一个大问题是find / first有时会做一些奇怪的事情,如果它找不到... Rails中的代码在某些情况下,字面上默认为all范围(这是我认为不应该发生的奇怪行为),因此对于只找到单个项目的范围,我通常不会打扰范围并使用你原来的类方法。