问题
Consider a User model with the following fields:
- First name (required)
- Last name (required)
- Email (required)
- Password (required)
- Phone (required, size: 10 digits)
- Address (required)
And a multi-step signup form with the following steps:
- 1st step with fields First Name, Last Name, and Email
- 2nd step with Password, Phone and Address.
How would you create a solution to validate the input in each step?
The standard ActiveRecord's way doesn't works, since it validates all fields at once.
I've created a solution for this problem but it turned out in a complicated code, so I'm looking for alternatives.
回答1:
Personally I would let the model manage it's own validation and move the logic for managing validations for each step to that.
Now, this is probably not the most elegant way to do it but its effective and doesn't clutter the code too much.
Add a step transient attribute to the model.
attr_accessor :step
Add the following method to the model to check if on right step:
def on_step(step_number)
step == step_number or step.nil?
end
The reason for step.nil? - this has the advantage that if you want to use validation on this model without using steps simply don't assign a value for step on your model and the method will allows return true enabling the validation to always be carried out.
Change validations to process only if on right step or to bypass if not using steps
validates :first_name, if: "on_step 1", presence: true
validates :last_name, if: "on_step 1", presence:true
validates :email, if: "on_step 1", presence:true
validates :password, if: "on_step 2", presence:true
validates :phone, if: "on_step 2", format:{ with: TEL_REGEX }, allow_blank: false
validates :address, if: "on_step 2", presence:true
Of course don't forget to set the current step for the model, for example by hard-coding it in a hidden field of the form (if rendering separate forms for each step) and change your params to receive it.
来源:https://stackoverflow.com/questions/40578350/multi-step-activerecords-model-validation