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.
Related
I have a comments model that is currently working with Articles. I would now like to have users be able to comment on the Coffeeshop reviews. Am I able to use the same comment table, or should I have a separate one (feels janky). I've not long been building with RoR (a few weeks) so still trying to get the hang of the basics.
Would I nest them in routes.rb (and how)
resources :coffeeshops do
resources :articles do
resources :comments
end
or
resources :coffeeshops do
resources :comments
end
resources :articles do
resources :comments
end
My models look like:
User
class User < ApplicationRecord
has_many :comments
end
Comments
class Comment < ApplicationRecord
belongs_to :user
belongs_to :article
belongs_to :coffeeshop
end
Articles
class Article < ApplicationRecord
has_many :comments, dependent: :destroy
end
Coffeeshops
class Coffeeshop < ApplicationRecord
has_many :comments, dependent: :destroy
I'm then assuming I need a foreign key to tie the user and comments together, and then also the comments to the article/coffeeshop.
I'd use a polymorphic association.
http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
class User < ApplicationRecord
has_many :comments
end
class Comment < ApplicationRecord
belongs_to :user
belongs_to :commentable, polymorphic: true
end
class Article < ApplicationRecord
has_many :comments, as: :commentable
end
class Coffeeshop < ApplicationRecord
has_many :comments, as: :commentable
end
For some more information about setting up the routes/controller:
https://rubyplus.com/articles/3901-Polymorphic-Association-in-Rails-5
http://karimbutt.github.io/blog/2015/01/03/step-by-step-guide-to-polymorphic-associations-in-rails/
You can use comment model for both comments for articles and coffeeshops, but (because by default rails uses ids as primary and foreign keys I assume you use ids too) you will have to add column to comments table, where you set the comment type (You can create Enumerator in comment model, where you set 2 possible value types, each for article and coffeeshop models). If you don't add the column it will result in weird, hard to track bug where you can see comments for article on coffeeshop with same id and vise-versa.
UPD: he's little guide on using enums for rails models: http://www.justinweiss.com/articles/creating-easy-readable-attributes-with-activerecord-enums/ you will have to use it not in actual add comment form, but behind the scenes.
Here is my models:
class User < ActiveRecord::Base
has_many :products
has_many :comments
end
class Product < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :product
end
I need to get comment records from current user products only
How do I do that? thanks
If we move the relationships to use a has_many: comments, through: products you can probably get what you're after:
class User < ActiveRecord::Base
has_many :products
has_many :comments, through: products
end
class Product < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :product
end
Now you can do user.comments.
The rails docs are here, which say:
A has_many :through association is often used to set up a many-to-many
connection with another model. This association indicates that the
declaring model can be matched with zero or more instances of another
model by proceeding through a third model. For example, consider a
medical practice where patients make appointments to see physicians.
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
I have a model Article and model User. In users, there will be one creator of the article and many readers. How do I link these together?
I was thinking:
class Article < ActiveRecord::Base
has_and_belongs_to_many :users
has_one created_by, through: :user (????)
end
class User < ActiveRecord::Base
has_many :articles
end
You can do like this
class Article < ActiveRecord::Base
has_and_belongs_to_many :users
has_one created_by_user,:class_name => 'User'
end
If you want to specify a custom foreign_key(which is useful in these cases),you can specify a foreign_key option
class Article < ActiveRecord::Base
has_and_belongs_to_many :users
has_one created_by_user,:class_name => 'User',:foreign_key =>'your_custom_fkey'
end
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