Rails partial validations depending on conrtoller

北城余情 提交于 2020-01-25 06:42:18

问题


I am using devise for user registrations, meaning, that by default new user is registered through registrations_controller. So by clicking button "Register" user is redirected to a new_user_registration path.

My registration form however has two steps. In first step (new_user_registration) I am asking for a name and password. In the second step (users_controller), when user is saved, I am asking for address. This I am doing with wizard gem:

    def create
    @user = User.new(params[:user])
    if @user.save
      session[:user_id] = @user.id
      redirect_to user_steps_path
    else
      render :new
    end
  end

So, those a kind of partioal validations, but I cannnot validate depending in the step, as the first part of my form is handeled through registrations controller. The second part is however in the users_controller. It's getting complicated here and I would like to know, if I can validatede depending on the controller. Like:

validates :first_name, presence: true, if: -> { new_user_registration_path }
validates :last_name, presence: true, if: -> { new_user_registration_path }
validates :street, presence: true, if: -> { new_user_path }

I know, like this, it makes no sence, but maybe it helps to understand my thinking behind. Also, maybe I can work with smth. like:

validates :first_name, presence: true, if: -> { @user.save }
validates :last_name, presence: true, if: -> { @user.save }
validates :street, presence: true, if: -> { @user.update}

So basically, when creating a new user, I would validate if name and password is present. And when then adding address (it's an update action for user), I will check if address is present. Does anyone has experince with forms like this?

Another thought, maybe, I can skip registrations controller, redirecting directly to the user and creating two steps for partial validations? But as I am working with devise, I don't know, if I can just go throught users controller, skipping new_user_registration path. I did it, how it was advised on the wicked tutorial, but still ended up in the registrations controller:

 def create
      super
  end
 def update
      super
  end

Thanks!


回答1:


The best solution to this type of problem is to use form objects. See this example and the gem Reform.

With form objects, each HTML form is processed via a form object. In your example you could have a "User Registration" form, and a "User update" form. The key point is that the validation is done by the form and not the model. That way the validation is relevant to the current form input, and you avoid the issues of classing validation rules.




回答2:


It's as easy as that:

validates :first_name, presence: true, :on => :create
validates :last_name, presence: true, :on => :create
validates :street, presence: true, :on => :update
validates :house_number, presence: true, :on => :update
validates :city, presence: true, :on => :update
validates :zip_code, presence: true, :on => :update

Clearly "Sign-Up" creates a User. And the wizard_steps just update the user. So for this simple example this works perfectly and raises validation errors according to the controller action.



来源:https://stackoverflow.com/questions/59839813/rails-partial-validations-depending-on-conrtoller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!