Search code examples
ruby-on-railsrubyruby-on-rails-3.1devisesti

Rails employer and employee devise


I am trying to figure out how to structure this please help: I need users to be able to sign up as either an employer or employee. The employer basically is the company and the employees are the people employed at that job. I want to know how to keep a record of when/if the employee was hired and terminated from the job. Would a has_many:through assotiation work for this or better yet is there a gem that I am overlooking that could help me with this?


Solution

  • This is a classic case of the hierarchical object model, so you have to think about this problem in terms of the objects involved and their relationships to each other. Think about the way a business works in real life:

    Employer -> Employees NOT Employer -> Manager etc. -> Employees

    A good example of this system model is that of GitHub. On GitHub, users can belong to Organisations. They can also create them and administrate them, managing members etc. (hiring and firing in your case). Therefore a much better way of modelling this system is having it be User-centric rather than a split of two different classes of User.

    As stated in a previous answer, Employers (or Businesses in this sense) should not be considered as users of the system as they won't be acting on the state of the program, users will. Therefore, I personally think STI is a little overkill for this system model.

    So...

    All people employed in a business are employees, but not all employees have the same level of authority (Managers will have more authority than Junior employees for example). Therefore you should model a Business, which has many Employees. Those Employees will have varying levels of authority based on their position:

    • can_hire?
    • can_fire?
    • etc.

    You could also create a method that would tell you when this Employee was hired/fired. These could return a date/time if they were hired/fired or nil if not. nil in this sense would obviously imply they haven't yet been hired/fired.

    When it comes to managing the abilities of different users, their level of authority is defined by what they can and cannot do. You can of course apply preset roles to this situation with a simple method that checks the above methods. For example:

    def manager?
      self.can_hire? and self.can_fire?
    end
    

    You would then also define an ability that would allow the creation of a Business:

    def can_create_business?
      self.manager?
    end
    

    Note: you can use scopes to achieve this elegantly.

    You can also sub-class a basic User model for your roles, or create a Role class that defines the above methods and acts on a given User model. You can then create individual roles and subsets of roles.

    Arguably, there are some cases where allowing the creation of employers/businesses and employees as separate entities that can both act on the state of the program are useful. If the Business can perform more than just simple administration functions then this might be worth it. In which case, I would still not consider the business as a User model. I would require a special user account be created along with the Business which would have a role of Business Administrator or something similar.

    This model follows some of the most basic principles in programming and Computer Science as a whole, so I hope it sheds a little light on your problem. Of course there are a number of gems available that have this functionality built-in, namely Devise and CanCan/CanTango, although I would personally build this system myself.