【问题标题】:Is there a way of doing filtering joined associations using named scope?有没有办法使用命名范围过滤加入的关联?
【发布时间】:2009-07-27 09:16:32
【问题描述】:

我有以下关联模型

class Enrollment < ActiveRecord::Base
  has_many :addresses
end

class Address < ActiveRecord::Base
  belongs_to :address_type
end

目前我正在使用以下(我认为很难看)来过滤掉某种地址类型的注册地址。

class Enrollment < ActiveRecord::Base
  def local_address
    adds = []
    addresses.each do |add| 
      adds << add if add.address_type.name == 'Local'
    end
    adds.last
  end
end

有没有办法使用命名范围做同样的事情?

【问题讨论】:

    标签: ruby-on-rails named-scope


    【解决方案1】:

    通用解决方案:

    class Address < ActiveRecord::Base
      belongs_to :address_type
      named_scope :local, { :conditions => { :address_type => { :name => "Local" }}}
    end
    

    这允许您执行以下操作:

    Enrollment.find(12).addresses.local  # Association extended with .local method
    Address.local.all                    # Class methods extended with .local method
    

    命名范围可以在您仅使用“本地”地址的所有情况下提供帮助。

    【讨论】:

    • 您的解决方案出现以下错误。 Mysql::Error: Unknown column 'address_type.name' in 'where clause': SELECT * FROM addresses WHERE (addresses.enrollment_id = 8) AND ((address_type.name = 'Local') AND (addresses.enrollment_id = 8)) ORDER BY addresses.id DESC LIMIT 1 似乎我们必须使用连接语句。
    【解决方案2】:

    参考以下 stackoverflow 帖子,我设法解决了我的命名范围查询

    Rails named_scopes with joins

    基本上我需要在查询中做连接

    class Address < ActiveRecord::Base
      belongs_to :address_type
      named_scope :local, { 
        :joins => "INNER JOIN address_types ON address_types.id = addresses.address_type_id",
        :conditions => "address_types.name = 'Local'"
      }
    end
    

    如此有效,我可以将 Enrollment 的“local_address”方法重写为

    clss Enrollment < ActiveRecord::Base
        def local_address
          addresses.local.last
        end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      • 1970-01-01
      • 2015-05-10
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2023-01-14
      相关资源
      最近更新 更多