4

In my rails app, a user can go along to events -

user.rb

has_many :attendances
has_many :events, through: :attendances

event.rb

has_many :attendances
has_many :users, through: :attendances

... with an attendance table which is made up of event_id, user_id and some other bits and pieces -

attendance.rb

belongs_to :user
belongs_to :writers_event

When looking for a particular attendance I find myself using .where ... .first - e.g.

attendance = Attendance.where(user_id: @user.id, event_id: this_event_id).first

And it strikes me that I missed the class where we talked about using something like find_by in this type of situation - in other words, where you are confident that you are looking for something unique. It might not matter, but searching for a collection then taking the first object from it feels wasteful and wrong.

Is there a better way?

I had a look around, and this was closest, but does not (I don't think) really cover it. How to display unique records from a has_many through relationship?

Community
  • 1
  • 1
dan
  • 1,030
  • 1
  • 9
  • 24

3 Answers3

5

It's actually pretty straightforward:

attendance = Attendance.find_by(user_id: @user.id, event_id: this_event_id)

You just pass the same conditions to find_by, and it returns you the first record.

There is one catch though. By using find_by, you will get nil, if nothing is found. If you need to get an ActiveRecord::RecordNotFound raised, if nothing is found, you can use find_by!.

Yury Lebedev
  • 3,985
  • 19
  • 26
3

You can use find_by for this:

attendance = Attendance.find_by(user_id: @user.id, event_id: this_event_id)

Although behind the scenes, it is doing a look-up and taking the first.

However, you can get a bit more help from rails here:

current_user.attendances.find_by(event_id: this_event_id)
A Fader Darkly
  • 3,516
  • 1
  • 22
  • 28
2

Try this one:

Attendance.find_by_user_and_event(@user.id, this_event_id)

If the record not found then it return nil. If you want to raise the exception

Attendance.find_by_user_and_event!(@user.id, this_event_id)
Kh Ammad
  • 1,085
  • 9
  • 12