Reputation: 175
I've been struggling, and couldn't find the right answers by myself.
For example, I have two separated associations
Profile
that belongs_to User
Comment
that belongs_to User
Both Profile
and Comment
have a user_id foreign key
Through Comment
I can easily access user like Comment.first.user
for example. But I can't do like Comment.first.user.profile (How can I do this?)
Can I join the results in a single query just with the user_id? Like Comment.joins .. ? I just want to know if this is possible, and if I can get some references I can do a research.
For example, I have this query for User.find(1)
id:12 | email:[email protected]
And I have this query for User.find(1).profiles
name: Fire | lastname: Fox | id_user: 12
Is it possible to obtain a result like this in ActiveRecord?
email:[email protected] | name: Fire | lastname: Fox
Also, can I do this with .all, instead of with .find or .where?
Comment model
class Comment < ApplicationRecord
belongs_to :user
end
Profile model
class Profile < ApplicationRecord
belongs_to :user
end
User model
class User < ApplicationRecord
has_one :profile
has_many :projects
has_many :comments
accepts_nested_attributes_for :profile
end
Upvotes: 0
Views: 510
Reputation: 23661
Sol 1: If you want to fetch it in one query
You need to join Profile
through User
and you can query like this
Comment.joins(user: :profile)
.select('users.email', 'profiles.name', 'profiles.lastname')
.where(id: 123)
Sol 2: You just need to add a through
association
class Comment < ApplicationRecord
belongs_to :user
belongs_to :profile, through: :user
end
and now you can access it like
comment = Comment.first
comment.user.email #=> "[email protected]"
comment.profile.name #=> "Fire"
comment.profile.lastname #=> "Fox"
You can also use delegate
but that will fire 2 queries
class User < ApplicationRecord
has_one :profile
has_many :projects
has_many :comments
accepts_nested_attributes_for :profile
delegate :name, :lastname, to: :profile, allow_nil: true
end
And now you can directly call name
and lastname
on user
comment = Comment.first
comment.user.email #=> "[email protected]"
comment.user.name #=> "Fire"
comment.user.lastname #=> "Fox"
Upvotes: 2