Rails: 基于关联值的 ActiveRecord 查询

我有两个模特。ReportServer,它们具有属于和具有多个关系。我使用 delegate创建了一个访问器方法,该方法允许 Report查找其关联的 Server.company_id。现在,我想在 Report上运行一个查询,它允许我找到与具有特定 company_id属性为5的特定 Server相关联的所有 Report

这是我的两个模特。是的,我知道当前的查询不会工作,因为 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

服务器

class Server < ActiveRecord::Base


attr_accessible :company_id


has_many :reports


end
57008 次浏览

这个应该能行

Report.joins(:server).where('servers.company_id = ?', 5)

您也可以像这样添加一个作用域

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

然后写作

Report.with_company_id(5)

您可以执行如下查询:

Report.joins(:servers).where(:servers => {:company_id => 5})

对我来说,这是原始 SQL 的更干净的解决方案。

我正在使用 Rails 4.1.7,而这个被接受的答案对我来说并不起作用,起作用的是

Report.joins(:server).where(:servers => {:company_id => 5})

请注意,这个差异是 where 子句中的复数形式(: server 而不是: server)中的键

这可能是一个过度杀伤,但我们有 阿瑞尔:

# Get the SQL


# arelise will return the SQL (string)
def arelise(company_id)
# Tables to query
reports = Report.arel_table # Main table
servers = Server.arel_table.alias('servers')


reports
.join(servers, Arel::Nodes::InnerJoin).on(reports[:server_id].eq(servers[:id]))
.where(servers[:company_id].eq(company_id))
# Select all (*)
.project(reports[Arel.star])
.to_sql
end


sql = arelise(1)
# puts sql


# To Execute:


reports = Report.find_by_sql(sql)


# puts reports