The User model appears almost in every Rails application and there are different types of users in our apps (admins and members at least). We often have different roles that are allowed to edit only specified fields or select only specified values.
In our application we have app admins and company (account) admins along with regular members. Company admins should be restricted to create only company admins and company members of their company. Regular members cannot change theirs role or company. App admins are allowed to do anything with users.
As both app admins and company admins have similar functionality it’d be good to have a one controller to manage users. We may have something like this in the admin/users controller:
1 2 3 4 5 6 7 | |
But we need to restrict company admins from creating application admins and forbid changing their company. It means that we need to use different validations and different attr_accessible attributes. It can be achieved using attr_accessor in the User model or some complex parameter filtering in the controller, but let’s imaging how the controller code can be written to keep it simple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
In order to make the code above work it’s possible to use inheritance:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
So we introduced User::AdminContext and User::CompanyAdminContext to be used in different cases. They have their own attr_accessible attributes and validations. Also we implemented the base User::Context to make contexts to use the same model_name as the User model.
This way allows the controller to choose a model behavior and the model isn’t got polluted with complex code.