Reputation: 8372
I would like to make a self join association which has two relationships
has_many and belongs_to (one)
I've found 2 ways to do this but I am not sure which one is more accurate, for example in this answer has_many and belongs_to within same model there is a relation between employee and manager, manager has_many employees, and employee belongs_to manager
the solution was to add a field called manager_id, so if the user is a manager then the manager_id will be null
, if an employee then manager_id will be the id of the manager.
The associations look like this :
has_many :employees, class_name: "User", foreign_key: :manager_id
belongs_to :manager, class_name: "User", foreign_key: :manager_id
The SECOND solution which I found here Rails Associations - has_many => :through - but same model has the following relation : post has_many related_posts and related_post belongs_to post
The solution here was to create two separate tables, one for posts and one for related_posts like this :
create_table "posts", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "related_posts", :force => true do |t|
t.integer "post_id"
t.integer "related_post_id"
t.datetime "created_at"
t.datetime "updated_at"
end
and the associations look like this :
class Post < ActiveRecord::Base
has_many :related_posts_association, :class_name => "RelatedPost"
has_many :related_posts, :through => :related_posts_association, :source => :related_post
has_many :inverse_related_posts_association, :class_name => "RelatedPost", :foreign_key => "related_post_id"
has_many :inverse_related_posts, :through => :inverse_related_posts_association, :source => :post
end
class RelatedPost < ActiveRecord::Base
belongs_to :post
belongs_to :related_post, :class_name => "Post"
end
Now I am not sure which way to go, the first solution looks simple and the idea was to add an additional field called manager_id (or can be post_id if we are working with posts) which will be null for all the managers people, I imagine having a lot of records with null value on that field which seems not correct...
the second solution looks good but the wrong thing I feel about it is the relation has_many :inverse_related_posts_association
which seems like a related_post has also other related posts / or maybe a related_post belongs to many posts (I am not sure).
In my case I want something like post has_many related_posts and a related_post belongs_to (one) post
Upvotes: 1
Views: 816
Reputation: 578
I'd go with the first option, unless you have a very compelling reason to take second approach. It is simple and obvious. And you can always refactor your code later.
There's nothing particularly bad about having nulls in a column, as long as the column is relevant for all records. In your case, NULL in manager_id would mean 'this person does not have a manager'. Is NULL value relevant here? My answer is yes.
NULL means the value is unknown or no value. Rails statement @person.manager.present?
will properly return true
for people who have manager defined, and false
for those who don't have a manager. When looking at a database record for any particular person, NULL in the manager_id field will convey the same meaning.
Upvotes: 1