Rails display attribute through indirect association - ruby-on-rails

New to rails here. My associations are setup as below, it might not be the ideal way so any recommendation is greatly welcomed:
User has many posts (posts table has user_id)
User has one profile (profile table has user_id)
Within my post controller view, I want to display the name of the profile (profile.name) that belongs to the user who owns the post.
My naive first guess was <%= #post.user.profile.name %> but that obviously didn't work.
This is the association defined in my models:
class User < ActiveRecord::Base
has_many :posts
has_one :profile
end
class Post < ActiveRecord::Base
belongs_to :user
end
class Profile < ActiveRecord::Base
belongs_to :user
end
This is the code in the view: <%= #post.user.profile.name %>
The error is undefined method profile

you have to mention the following in your models
user.rb
has_many :posts
has_one :profile
profile.rb
belongs_to :user
post.rb
belongs_to :user
Then <%= #post.user.profile.name %> should work.
And if still there is a problem in your data

You need to define a belongs_to relation in posts and profile model to get this work. Eg:
class User < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :user
end
Do the same with the profile model as well

Related

How to make references between two existing classes?

Rails newbie here; so I have three classes - user, article, comment - where,
class User < ActiveRecord::Base
has_many :articles
end
class Article < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :article
end
Now I'm wanting the comments to be user specific i.e. each comment will be linked to a user (just how every article is linked to a user). How do I go about doing that apart from adding has_many and belongs_to in user.rb & comment.rb? I hope I made myself clear.
Add similar relations to User and Comment. So a comment will have an user_id as well as an article_id.
class User < ActiveRecord::Base
has_many :articles
has_many :comments
end
class Article < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :article
belongs_to :user
end
You will have to write a migration after alerting your models to add an user_id field to your comments table.
rails g migration AddUserRefToComments user:references
Then run rake db:migrate. Hope that helps.

Can object have 2 parents in rails?

Hi I have a comment object, and I use polymorphic association, so it can belongs to many other objects. But I also want them to belong to users.
Now I can, call comment.comment_owner and I get the object that was commented by this comment.
As for the user I have a user_id field in the comment object, I pass the user id through the form. But when I try to get owner user by comment.user I get an error. Right now I`m getting user by User.find(comment.user_id). But this looks bad.
Is there a way to pass the user id. So I can get User owning a comment by comment.user
My associations:
class Comment < ActiveRecord::Base
belongs_to :comment_owner, polymorphic: true
end
class User < ActiveRecord::Base
has_many :comments, as: :comment_owner
end
class Posts < ActiveRecord::Base
has_many :comments, as: :comment_owner
end
Why not just
class Comment < ApplicationRecord
belongs_to :user
end
First of all, in my opinion comment_owner is not a good name for what you're designing here. Comment owner would suggest an ownership relation (rather a person or someone). I'd rather call it commentable as these object are being commented on.
If this relation is meant to be a polymorphic then you should have commentable_type and commentable_id (or comment_owner_type and comment_owner_id if you really prefer the original) as polymorphic => true expects to have those two fields (named as: relation_name_type and relation_name_id).
If you then have a Comment object you get the user commented by calling comment.commentable (or comment.comment_owner in case you decide to keep your naming).
[EDIT]
As you said, you want to have two parents. If I get this right you just want to have two relations - this means that if you just modify your code to:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
belongs_to :author, class_name: 'User'
end
class User < ActiveRecord::Base
has_many :comments, as: :commentable
has_many :notes, class_name: 'Comment'
end
class Post < ActiveRecord::Base
has_many :comments, as: :commentable
end
You will have your polymorphic relation as well as the ownership.

Rails: collect through association?

For example, Topic has many comment, and each comment belongs to a user.
How can I get all the users have commented on the one topic, efficiently?
Now I doing this by
#commenters = #topic.comments.collect do |post|
user = post.user
user
end
And, how can I make #commenters uniq? Turn it into an array?
You could define through relation
Rails through association
Topic model
class Topic < ActiveRecord::Base
...
has_many :comments
has_many :users,
:through => :comments # add this line, it will enable association
...
end
Comment model
class Comment < ActiveRecord::Base
..
belongs_to :topic
belongs_to :user
..
end
User model
class User < ActiveRecord::Base
...
has_many :comments
...
end
then you can find users on topic.
#topic.users

Possible to filter an ActiveRecord query based on multiple "belongs_to" relations?

class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
class User < ActiveRecord::Base
has_many :posts
end
class Category < ActiveRecord::Base
has_many :posts
end
I want to get all the posts that have a relation to user AND category. Is any similar possible:
user.category.posts
Or do I need to do:
user.posts.where(category_id: category.id)
You have 1-M relationship between User and Post.
In User model association should be has_many :posts (note plural)and not has_many :post(singular).
Update your model User as below:
class User < ActiveRecord::Base
has_many :posts ## Plural posts
end
To answer below question:
get all the posts that have a relation to user AND category
Assuming that you have local variables user and category as an instance of User model and Category model respectively.
For example:
user = User.find(1); ## Get user with id 1
category = Category.find(1); ## Get category with id 1
user.posts.where(category_id: category.id) ## would get you what you need.
Also, user.category.posts will not work as User and Category models are not associated.
Try:-
user.posts.where(category_id: category.id)
Change your association like
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
class User < ActiveRecord::Base
has_many :post
belongs_to :category or has_one :category
end
class Category < ActiveRecord::Base
has_one :user or belongs_to :user
has_many :posts
end
in users table add column category_id,or add column user_id in categories,because you don't have relation between those two tables.if you don't have relation you can't use association API's.then you have to use manual API to fetch the data.like how you have mentioned your question.

RoR v2.3 Model associations

I was wondering how I'm suppose to associate my User, Post, and Comment models. It is suppose to be like so: The user can comment on any post and a post belongs to a user with a Boolean for being admin. I have been scratching my had for awhile trying to figure this out but nothing has made any sense at all.
Any help would be greatly appreciated.
In the most obvious arrangement Post would belong_to :user and has_many :comments, and Comment would both belong_to :user and belong_to :post. User would has_many :posts.
You can specify the following association in the model
# app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
# app/models/user.rb
class User < ActiveRecord::Base
has_many :comments
end
# app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
end

Resources