Rails:基于关联值的ActiveRecord查询

use*_*382 54 ruby activerecord ruby-on-rails associations

我有2个型号.Report并且Server有一个belongs_to和has_many关系.我创建了一个使用的访问器方法delegate,允许Report找到它的关联Server.company_id.现在,我想运行一个查询Report,允许我查找ReportServer具有特定company_id属性5 的特定属性相关联的所有内容.

这是我的两个型号.是的,我知道当前的查询不起作用,因为Report没有属性company_id.

不,我不想存储company_id内部,Report因为该信息不属于Report.

报告

class Report < ActiveRecord::Base

 belongs_to :server

 delegate :company_id, :to => :server

    class << self

        def method(url, base_url)
            #Report.where(company_id: 5)
        end
    end

end
Run Code Online (Sandbox Code Playgroud)

服务器

class Server < ActiveRecord::Base

 attr_accessible :company_id

 has_many :reports

end
Run Code Online (Sandbox Code Playgroud)

Kap*_*ssi 77

您可以执行以下查询:

Report.joins(:servers).where(:servers => {:company_id => 5})
Run Code Online (Sandbox Code Playgroud)

对我来说,这是原始SQL的更清晰的解决方案.

  • 你不需要`.all`. (8认同)
  • "server"的第二个实例,".where(:server ...")应更改为".where(:servers ...".它需要复数形式,因为它是表的名称. (3认同)

Jos*_*ill 39

我正在使用Rails 4.1.7并且接受的答案对我不起作用.做了什么工作

Report.joins(:server).where(:servers => {:company_id => 5})
Run Code Online (Sandbox Code Playgroud)

请注意,区别在于where子句是多元化的键(:服务器而不是:server)

  • 在Rails 5.1.6上相同:) (4认同)
  • 谢谢。在Rails 4.2.5上也一样 (2认同)

Pat*_*ity 17

这应该可以解决问题

Report.joins(:server).where('servers.company_id = ?', 5)
Run Code Online (Sandbox Code Playgroud)

你也可以这样添加一个范围

scope :with_company_id, lambda {|id| joins(:server).where('servers.company_id = ?', id) }
Run Code Online (Sandbox Code Playgroud)

然后写

Report.with_company_id(5)
Run Code Online (Sandbox Code Playgroud)

  • 我认为“ where”字符串中的“服务器”应为复数形式。 (2认同)