Rails 部分验证取决于控制器

Rails partial validations depending on conrtoller

我正在使用用户注册设计,也就是说,默认情况下新用户是通过 registrations_controller 注册的。因此,通过单击 "Register" 按钮,用户将被重定向到 new_user_registration path.

但是我的注册表有两个步骤。在第一步 (new_user_registration) 中,我要求输入名称和密码。在第二步(users_controller)中,当用户被保存时,我要求地址。我正在使用向导 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

所以,这些是一种部分验证,但我无法根据步骤进行验证,因为我的表单的第一部分是通过注册控制器处理的。然而,第二部分在 users_controller 中。这里变得越来越复杂,我想知道我是否可以根据控制器进行验证。喜欢:

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 }

我知道,像这样,没有任何意义,但也许有助于理解我背后的想法。另外,也许我可以和 smth 一起工作。喜欢:

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

所以基本上,在创建新用户时,我会验证名称和密码是否存在。然后添加地址时(这是用户的更新操作),我将检查地址是否存在。有人用过这样的表格吗?

另一个想法,也许我可以跳过注册控制器,直接重定向到用户并为部分验证创建两个步骤?但是当我在设计时,我不知道,如果我可以通过用户控制器,跳过 new_user_registration 路径。我做到了,它是如何在邪恶的教程中被建议的,但仍然在注册控制器中结束:

 def create
      super
  end
 def update
      super
  end

谢谢!

解决此类问题的最佳方法是使用表单对象。参见 this example and the gem Reform

对于表单对象,每个 HTML 表单都是通过表单对象处理的。在您的示例中,您可以有一个 "User Registration" 表单和一个 "User update" 表单。关键是验证是由表单而不是模型完成的。这样验证与当前表单输入相关,并且您避免了分类验证规则的问题。

就这么简单:

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

显然"Sign-Up" 创建了一个用户。 wizard_steps 只是更新用户。因此,对于这个简单的示例,它可以完美地工作并根据控制器操作引发验证错误。