trowse
trowse

Reputation: 204

Can't access attributes through Has many

Tried to dumb down my models to show the important stuff it seems like things are missing let me know.

I'm trying to access the Owner of a session via @session.owner in my view. The owner is associated with an attendee and all the attendees are associated with the session via a has_many.

It seems like self.attendees does not return any records. I'm sure I'm missing something obvious. Thanks in advance if you can help!

Cheers, Tyler

Session Model

class Session < ApplicationRecord
  has_many :attendees

  def owner
    self.attendees.each do |attendee|
      if attendee.role == "Owner"
        "#{attendee.user_id}"
      end
    end
  end

end

Attendee Model

class Attendee < ApplicationRecord
  belongs_to :session

end

Upvotes: 0

Views: 671

Answers (2)

Nicholas.V
Nicholas.V

Reputation: 1936

There are a couple things that stand out. Firstly, the way you have implemented the owner method is not very efficient having to query for each record and check the role attribute. The association can be defined using Active Record Association methods. E.g. you can define a scope when declaring associations.

In order to investigate your issue, that is, session.attendees is not returning any records, I recommend the following:

  1. Verify that you are following the rails convention and have the correct reference column. Attendee should have session_id column.
  2. Write some specs, or at the very least load the rails console and verify that your has_many :attendees association is working as expected by creating some test records and seeing some records returned. This will most likely reveal any problems with your code.

Next, declare your "session has owner" association by using active record associations. Think about what you want here: should session.owner return the attendee record or the user record (in our example you indicate that attendee belongs to a user?) Assuming that session.owner returns an Attendee record, your association may look like this: has_one :owner, -> { where role: 'Owner' }, class_name: 'Attendee'. (Please note this is an untested example).

For more information on has_one associations see http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_one

Upvotes: 1

Alex Kojin
Alex Kojin

Reputation: 5204

In your case each will continue work after find owner and will return nil.

class Session < ApplicationRecord
  has_many :attendees

  def owner
    user_id = nil
    self.attendees.each do |attendee|
      if attendee.role == "Owner"
        user_id = "#{attendee.user_id}"
        break
      end
    end

    user_id
  end

end

I've rewrite your code to use sql approach to find owner.

class Session < ApplicationRecord
  has_many :attendees

  def owner
    self.attendees.find_by(role: "Owner").try(:user_id)
  end
end

Upvotes: 1

Related Questions