Rails:如何有条件地"validates_presence_of"?例如到达某个页面时?

Rails: How do I "validates_presence_of" conditionally? For example when reaching a certain page?

例如我有一个用户注册,在注册过程中只需要一个密码和用户名。一旦他们点击 "shop",他们必须输入地址和城市才能继续。

目前每个用户都必须输入用户名、密码、城市和地址才能注册。我如何拆分它并且仅在用户单击 "shop" 时才需要它?

我正在使用设计。

我想将用户发送到一个页面,上面写着 "if you would like to continue, please let us know your address and city"

只需向您的模型添加一个名为 can_shop? 的方法或类似检查是否已提供所有必填字段:

def can_shop?
  [city, address].all?(&:present?)
end

然后您可以使用它来禁用按钮或在您的控制器中创建一个 before_action:

before_action :check_if_can_shop

private

def check_if_can_shop
  return if current_user.can_shop?
  redirect_to edit_user_path(current_user), notice: "if you would like to continue, please let us know your address and city"
end

我们自然会留下一个 UX 元素 - 您需要将表单中的这些字段标记为 "optional, but required to shop"。稍后您可以将 original_url 作为额外参数传递,然后您可以使用该参数将用户重定向回他完成所有必填字段的时间。

另一件事是你可以使用验证上下文并在你的 user_update 操作中使用正确的上下文 - 这样一旦你将用户重定向回表单,他将在他错过 normally-optional- 时看到正确的验证错误但现在是必填字段。

您可以通过嵌套表单来做到这一点,并在 rails 中进行自定义验证。

例如:

class User < ActiveRecord::Base
 validates :my_method_name, if: :page_reached?

 def page_reached?
    -- do stuff for page number -- 
 end

 def my_method_name
    errors.messages :base, "Cities should not be empty."if cities.empty?
 end

 def my_method_name
    errors.messages :base, "Address should not be empty."if address.empty?
 end
end