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.