Skip some validations on different controllers accessing the same model
I am not sure if this problem is due to a lack of knowledge or a problem in my design.
Essentially, I want my users to be able to login and be given a default开发者_运维知识库 role. Later on, they can become "Managers" and need to go to a second sign up form to achieve this.
However, the difference between a standard user and a manager is very minimal in terms of what data they have (but very different in terms of what permissions they are allowed). Therefore, I have chosen to use a single User model for both of them and then two controllers, users_controller and managers_controller, to serve the two different sign up forms and the resulting create requests. It might be that this just the wrong way to handle this situation.
I have some validations setup in this model and I want to be able to ensure that some of these validations are fired for on the initial sign up form (when a guest becomes a user, via the users_controller) and the rest are fired on the second sign up form (when a user becomes a manager, via the managers_controller). However, I use, for example validates_presence_of
then it checks the validation on both forms and complains that I am not, for example, asking my normal users for a date of birth.
I know how to skip checks on particular actions but how to do I this for different controllers?
Validations are on the model side, so they are independent on controllers. BTW it seems that you are speaking about role based approach.
You can achieve your goals by using if
statement on validations.
validates :date_of_birth, :presence => true, :if => :manager?
def manager?
# It actually depends on your design.
# You can use any authorization library.
self.role == "manager"
end
For example, the popular one is cancan.
I suppose that User has some kind of attribute or association where its roles are stored. Every validator in rails (like validates_presence_of) can be conditional in a way that it is only fired when the Proc/Method you supply via the :if option returns true. Within such a Proc, you could check, if the user is actually trying to become a "manager".
I recently had a similar problem, where validations had to be different depending on the state a particular model instance would be in. Have a look at the state_machine (http://github.com/pluginaweek/state_machine) gem which provides support for that. Perhaps this suits your scenario better.
How about
validates_presence_of :something, :if=>:manager?
def manager?
self.manager
end
Or to skip validations specifically you can do
@user.save(false)
from one of the controllers
精彩评论