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.
stepattribute? Granted, you might turn out to have some complicated controller code.validates :first_name, presence: true, if: lambda { |user| user.step === 1 }. If you find a good answer, the Rails community would love to know :) - JustinUserinstance all the way through? You could build one or two temporary non-Usermodels along the way and then convert them to a realUserwhen you're done. Same logic overall but the conditionalness of the validation would be handled by the separation of the models rather than a bunch of complexity inUser. - mu is too short