Reputation: 1192
I have the following models and associations:
class Organization
has_many :buildings
end
class Building
has_many :counters
end
class Counter
has_many :counter_records
end
class CounterRecord
belongs_to :counter
end
I would like to get something like this
organization.counter_records(dimension_day: start_date...end_date)
([dimension_day: start_date...end_date]
- it's condition).
How do I get counters records of organization
through all these models?
Upvotes: 2
Views: 55
Reputation: 52357
Look into Activerecord Querying guide.
Specifically you're interested in joins
:
Organization.joins(buildings: { counters: :counter_records })
.where(counter_records: { dimension_day: start_date...end_date })
.group('organizations.id')
You can create a method:
class Organization
def filter_counter_records(start_date, end_date)
self.class
.where(id: id)
.joins(buildings: { counters: :counter_records })
.where(counter_records: { dimension_day: start_date...end_date })
.group('organizations.id')
end
end
Now the following is possible:
organization = Organization.first
organization.filter_counter_records(start_date, end_date)
But more idiomatic/conventional option would be using associations:
class Organization
has_many :buildings
has_many :counters, through: :buildings
has_many :counter_records, through: :counters
end
Now you can just go with
organization = Organization.first
organization.counter_records.where(dimension_day: start_date..end_date)
The last step here would be setting up the scope
in CounterRecord
:
class CounterRecord
scope :by_date_range, ->(start_date, end_date) { where(dimension_day: start_date..end_date) }
end
And now
organization = Organization.first
organization.counter_records.by_date_range(start_date, end_date)
Upvotes: 5