Reputation: 4520
I have 2 models. Report
and Server
that have a belongs_to and has_many relationship. I created an accessor method using delegate
that allows a Report
to find its associated Server.company_id
. Now, I want to run a query on Report
that allows me to find all Report
that are associated with a specific Server
that has a specific company_id
attribute of 5.
Here are my two models. And yes I know the current query wont work since Report
does not have an attribute company_id
.
And no, I dont want to store company_id
inside of Report
since that information doesn't belong in 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
Server
class Server < ActiveRecord::Base
attr_accessible :company_id
has_many :reports
end
Upvotes: 76
Views: 63742
Reputation: 12092
This maybe an overkill but we have Arel:
# 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
Upvotes: 0
Reputation: 2716
You can perform a query like this:
Report.joins(:servers).where(:servers => {:company_id => 5})
To me, this is the cleaner solution to raw SQL.
Upvotes: 110
Reputation: 54734
This should do the trick
Report.joins(:server).where('servers.company_id = ?', 5)
you could also add a scope for this like so
scope :with_company_id, lambda {|id| joins(:server).where('servers.company_id = ?', id) }
and then write
Report.with_company_id(5)
Upvotes: 27
Reputation: 1067
I'm using Rails 4.1.7 and the accepted answer did not work for me. What did work is
Report.joins(:server).where(:servers => {:company_id => 5})
Note that the difference is the key in the where clause is pluralized (:servers instead of :server)
Upvotes: 49