ruby-on-railsrubymodel-associationsrails-models

Manager -> Employee association one level in rails


I want to create manager->employee association.

How to implement this design ? I created something closer(code is below) but in my design manager can have other manager.

class User < ApplicationRecord
  has_many :employee, class_name: "User", foreign_key: "manager_id"
  belongs_to :manager, class_name: "User", foreign_key: "manager_id"
end

Any help is highly appreciated!


Solution

  • What you have is a really standard self-joining setup (with a few small issues). You can limit the depth of the tree by just adding a custom validation:

    class User < ApplicationRecord
      # optional: true is needed in Rails 5+ since belongs_to is no
      # longer optional by default
      belongs_to :manager, class_name: 'User',
                           optional: true
      # pay attention to pluralization
      has_many :employees, class_name: 'User',
                           foreign_key: 'manager_id'
      # calls the custom validation we will define later
      validate :manager_must_be_a_manager, unless: :manager?
    
      def manager?
        manager.nil?
      end
    
      private
        # our custom validation method
        def manager_must_be_a_manager
          errors.add(:manager, 'is not a manager') unless manager.manager?
        end
    end
    

    So now if we run:

    user_1 = User.create!
    user_2 = User.create!(manager: user_1)
    User.create!(manager: user_2)
    

    The third line will raise ActiveRecord::RecordInvalid: Validation failed: Manager is not a manager.