csi
csi

Reputation: 9328

Rails has_many retrieve all records

# Events
has_many :attendees

# Attendees
belongs_to :event

How can I access All the Events with each Event's Attendees?
Event.all.attendees # obviously does not work

To do this for 1 event, we can do
Event.find(1).attendees
How can we do this for all events? Is there an automagic way or do we need a loop?

Upvotes: 1

Views: 275

Answers (2)

Andrey Deineko
Andrey Deineko

Reputation: 52357

Yes. there is. Have a read about AR query methods.

There are two main methods to look on:

joins and includes.

Event.includes(:attendees)

would load all events and it's attendees (whether there are any or none)

Event.joins(:attendees)

would select those events, which have assigned attendees.

With both options you can then iterate over events' attendees with a block.


Edit

Just a short clarification. I do understand, that you probably needed a result, that can be (but never should be) achieved this way:

Event.all.map(&:attendees) # would return a collection of attendees.

Such queries are evil, since they are fully loaded into memory before execution.

And the point of edit - you would "never" actually need such thing, as loading a collection of assigned attendees.

Why?

Because if you ever need a collection of attendees, operate on Attendee model, not Event or any other associated model.

What that mean, is that you can get some events meeting certain condition(s).

For example:

events = Event.where('start_date > ?' Date.today)

If you need Attendees for this event, you would rather do this

Attendee.where(event_id: events.ids)

then this

Event.where('start_date > ?' Date.today).map(&:attendees) #inefficient

I hope I made myself clear.

Upvotes: 2

MrYoshiji
MrYoshiji

Reputation: 54882

You can use eager loading to retrieve the Event and their associated Attendee in few SQL queries:

events = Event.includes(:attendees)
events.each do |event|
  event.attendees
end

Upvotes: 0

Related Questions