multiple belongs_to models in Rails - ruby-on-rails

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.

Related

Associate Rails active model with two different models

Is there a way to use inheritance with Ruby on Rails Active Model?
I have two models to which I want to add comments. It would be cool if I can just use one Comment model that could be associated with both models.
Look into Polymorphic Associations
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
class Article < ApplicationRecord
has_many :comments, as: :commentable
end
class Image < ApplicationRecord
has_many :comments, as: :commentable
end

Rails activerecord deep eager loading

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.

Rails models association not working?

thanks for this commmunity, it has helped me alot already. This is the first question I have to post myself, and it is somewhat specific to my project.
I have started from MHartls great rails tutorial.
There were models for Users and Microposts and I have added a Cars model, where each user can have a car (referenced by the car_id).
In the console I can create a user and a micropost, and assign the user to the micropost by stating post.user = michael and then it would set the post's user_id to michaels id.
I am trying to do the same for cars, where i can set a users car_id by stating michael.car = somecar but it gives an error even though the model associations LOOK exactly the same, and I have even remigrated the car_id to the user model as reference. See below:
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
belongs_to :cars
class Micropost < ActiveRecord::Base
belongs_to :user
belongs_to :car
class Car < ActiveRecord::Base
has_many :microposts, dependent: :destroy
has_many :users
accepts_nested_attributes_for :users
accepts_nested_attributes_for :microposts
Here is my last migration for the car_id:
class Addreferencecartousers < ActiveRecord::Migration
def change
add_reference :users, :car
add_foreign_key :users, :cars
end
end
in synch with what I had done for the user/micropost connection.
I am kind of lost on where else to look for why this does not work, does anyone have any hints/pointers on what I am missing here?
To address your problem, the belongs_to :cars in the User model should be belongs_to :car, but in a reality I believe it will be more sense to call it as has_many :cars rather than a belongs_to :car because a user can have many cars and a car belongs to user

Nested associates the rails way

I'm fairly new to Rails and I'm trying to gain a better understanding of how to be leverage the Rails framework for my associations.
While it's not specific for my app, the structure is similar -- for my example, I'll use the standard blog associates.
Example Models:
class Author < ActiveRecord::Base
has_many :posts, :through => :posts
end
class Post < ActiveRecord::Base
belongs_to :author
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
end
My challenge is that I want to select all comments that belong to a specific author. I understand how to reference post and author elements that are associated with a specific post:
comment_author = Comment.first
puts comment_author.post.author.name
But as I stated I'm trying to select all comments that belong to a specific author. I could accomplish this by doing a find_by_sql, but I want to ensure db independence and I want to do this the "Rails way."
Thanks!
You can use the has_many :through assocication:
class Author < ActiveRecord::Base
has_many :posts
has_many :comments, :through => :posts
end
#Femaref provided the exact answer to your question and you should accept it. Mine is merely a complement.
If an author can leave comments on posts, here is what you might want to do:
class Author
has_many :posts
has_many :comments
has_many :responses, through: :posts, source: :comments
end
class Post
belongs_to :author
has_many :comments
end
class Comment
belongs_to :author
belongs_to :post
end
To get all the comments left by sophia: sophia.comments
To get all the comments left on sophia's posts: sophia.responses
See the options for has_many (especially through and source)

Rails: How do I route unassociated resources?

I have four models:
class User < ActiveRecord::Base
has_many :posts
end
class Category < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :metric
has_many :comments
end
class Comments < ActiveRecord::Base
belongs_to :post
end
I'd like to be able to access a post within a certain category for a specific user. For example:
http://domain.com/users/1/categories/1/posts
Also I want to see a list of all categories if I visit:
http://domain.com/users/1/categories/
Since categories are fixed and the same for all users, User and Category don't have a direct association. Because of this, I'm not quite sure how to configure the routes.rb file to access posts within a category for a user. I'd appreciate any suggestions. Thanks!
You could use nested resources to do that like :
resources :users do
resources :categories
end
For more : http://guides.rubyonrails.org/routing.html#nested-resources

Resources