I have users, posts, and comments. Posts belong to users. Users have many posts.
Now where I'm confused is that users are supposed to be able to comment on others' posts.
How do I set up this association?
Should I write users have many comments, posts have many comments, comments belong to posts and users? or user has many comments through posts?
Also what columns should the model table have? Does it need user_id, post_id, content?
use has_many :through Association
User model:
has_many :posts
has_many :comments, :through => :posts
Post model:
belongs_to :user
has_many :comments
Comment model:
belongs_to :post
belongs_to :user
You are correct the first time.
Users have many comments. Posts have many comments. Comment belongs to User. Comment belongs to Post.
The comments table should have user_id and post_id.
So user.comments will be comments that a user has made. post.comments will be comments on that post.
This is an association to say "This user commented on this post."
Related
I have a DB schema where a shipment belongs_to two users even though the relation is between model to model.
The shipment can have a receiver_id and a sender_id. Both the receiver & sender are two different records in the same table (the user model).
I was wondering how can I establish a relationship in my rails backend for a shipment to belong_to a record where the user is the sender as well as another record in the same DB where the user is the receiver.
I'v been thinking for ages how to do it, and its very hard to come up with a solution. The only solution I have is to destroy the existing User model, and create two different models: a receiver & a sender. Or is there another solution for this? I've attached my DB schema in this thread.
Any help would much appreciated. Thanks in advance!
DB Schema
class Shipment < ApplicationRecord
belongs_to :sender, :class_name => "User"
belongs_to :recipient, :class_name => "User"
end
class User < ApplicationRecord
has_many :sent_shipments, :class_name => "Shipment", foreign_key: 'sender_id'
has_many :received_shipments, :class_name => "Shipment", foreign_key: 'recipient_id'
end
I am designing a relational database for projects and tasks. I want projects and tasks to be able to be classified or grouped by category.
If a project is shared by two or more users, I want each user to be able to categorize the project separately. Additionally, I want users to be able to share entire categories with each other, including all projects and tasks within that category. Therefore, here is the schema that I have come up with in terms of a basic ERD:
Here are my main models in Rails:
class User < ActiveRecord::Base
has_many :user_projects
has_many :user_categories
has_many :projects, :through => :user_projects
has_many :categories, :through => :user_categories
end
class Project < ActiveRecord::Base
has_many :user_projects
has_many :users, :through => :user_projects
has_many :tasks, :as => :taskable
end
class Task < ActiveRecord::Base
belongs_to :taskable, :polymorphic => true
end
class Category < ActiveRecord::Base
has_many :user_categories
has_many :users, :through => :user_categories
has_many :tasks, :as => :taskable
end
Is it okay to include a category_id foreign key in the User_Project join (junction) table like this? Also, do you see any problems with this schema in general? Any help will be greatly appreciated.
Since you asked if we saw any problems with the schema in general, ...,
The relationship between tasks and projects is not clear. If it's the taskable_id, that's a strange column name. Why not go with project_id?
There is also a lack of flexibility. You said that you want to allow users to share categories and your schema seems to support that. What I don't see is anything that allows two users to work on different tasks on the same project. That seems to be something that could happen in real life.
I'm puzzled about the User_Category table. Do categories apply to both users and projects?
I'm new to active record, I want to know the difference between has_one and belongs_to in associations.
Can anyone explain with a good example?
I want examples for has_one associations without using belongs_to in the second model.
The difference is in where the foreign key is stored.
So for example if a post belongs to a user, the post table will have a column user_id so the post knows which user it belongs to.
has_one only makes methods like some_user.post available.
See also: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Is+it+a+belongs_to+or+has_one+association%3F
Here is roughly what I have:
I have many companies that has many user through roles:
class Company < ActiveRecord::Base
has_many :roles, :dependent => :destroy
has_many :users, :through => :roles
end
and many users which can have many companies through roles:
class User < ActiveRecord::Base
has_many :roles, :dependent => :destroy
has_many :comapnies, :through => :roles
end
and many roles that bind the two together:
class Role < ActiveRecord::Base
belongs_to :user
belongs_to :company
end
The idea here is that a user can sign-in through a common email username and then have privileges assigned to each company. Role has a user_id and company_id keys along with a privilege column 'user_role' (i.e. guest, user, admin etc.).
Here is where being ruby-newbie fails me. When my user logs in I want to query which companies they have privileges on and switch that on the fly with a menu drop down. So they login and are active in 'Company A' and then they can switch to 'Company B'. When they switch the company_id is stored in a session variable (I already have their user_id stored with a functioning authentication system).
What is the best way to query this? I have a user_id and I want to retrieve a list of the company_id, company_name, 'user_role' etc. then use this to generate a pop-down list.
I have been playing with the console trying Role.Company.etc.etc but can't seem to figure this out. When I was doing this in PHP / MySQL before it would have been a complex join query. I am sure it's easier in Rails I jet can't seem to figure it out.
Any help would be appreciated.
Thanks,
Dan
You can get all of the companies a user has access to (for any role) via current_user.companies.uniq. The uniq part just ensures you don't have duplicate companies in the list (in the case a user has more than one role for a single company).
Thanks for everyones feedback. This got me looking at includes and joins again. I ended up looking at http://railscasts.com/episodes/181-include-vs-joins and the Rails API docs and cobbled together this:
Role.includes(:company).where(:user_id => session[:user_id])
I then loop through #role and I can pull role.role_name and role.company.name etc. Starting the query with the User.find(session[:user_id]) was complicating it.
A phone has many messages.
An email address has many messages.
A message either belongs to a phone, email, or neither. The belongs_to association is optional.
The following associations seem to work fine for these relationships:
Phone model has_many :messages
Email model has_many :messages
Message model does NOT have belongs_to :phones, :email
Is this okay or is there some proper way to specify a "can_belong_to" relationship?
It is completely correct unidirectional relation. Using both is sometimes called "curcular dependency" by some purists and may cause problems when using validates_associated.
From the other side using only has_many :messages may be not enough when you want retrieve phone information from one message. Generally it is matter of convenience.
The model with the belongs_to associations holds the foreign keys (e.g. messages table would have phone_id and email_id columns).
The belongs_to association combined with has_many lets you easily access associated records:
phone.messages
message.phone
So without the belongs_to and FK columns, the has_many association isn't very useful.
It seems like in this case you may want a many-to-many relationship such as has_and_belongs_to_many as a message can have many recipients.