I have the user model like :
has_many :users, class_name: 'User'
belongs_to :master_user, class_name: 'User', optional: true, inverse_of: :users
I Would like to find :
User.first.master_user it's ok
MasterUser.users but get an error : "NameError: uninitialized constant MasterUser"
CodePudding user response:
You are getting that error because you have not defined a MasterUser
model. I am guessing you only have a User
model as described in your question. If you want to find the users belonging to a "master_user" then you need to find a "master_user" first, then request its users. It would look something like this:
user_with_a_master = User.where.not(master_user_id: nil).first
master = user_with_a_master.master_user
master_users = master.users
CodePudding user response:
Here is an example of how to properly setup a self-referential association with a bit less confusing naming:
class User < ApplicationRecord
belongs_to :manager
class_name: 'User', # requied here since it cannot be derided from the name
optional: true,
inverse_of: :subordinates
has_many :subordinates,
class_name: 'User', # requied here since it cannot be derided from the name
foreign_key: :manager_id, # what column on the users table should we join
inverse_of: :manager
end
"Managers" here are not a separate class. While you could use single table inheritance to that purpose you should probally get the basics figured out first. Even if you did have a MasterUser
class you would get NoMethodError
since you're calling .users
on the class and not an instance of the class - that will never work and is a very common beginner misstake.
Note that this strictly speaking would actually work without the inverse_of:
option which is really just used to explicity set the two way binding in memory.
So in your case it should look like:
class User < ApplicationRecord
# class_name isn't required since it can be derided from the name
has_many :users,
foreign_key: :master_user_id,
inverse_of: :master_user
belongs_to :master_user,
class_name: 'User', # requied here since it cannot be derided from the name
optional: true,
inverse_of: :users
end
Note that the users table must have a master_user_id
column.