Ruby on rails Rails如何仅在更新时存在属性时调用自定义验证方法

Ruby on rails Rails如何仅在更新时存在属性时调用自定义验证方法,ruby-on-rails,ruby,ruby-on-rails-5,Ruby On Rails,Ruby,Ruby On Rails 5,我尝试只在自定义验证方法是新记录或属性在更新时出现时调用它 validates :mobile_number, presence: { message: 'Please provide your phone number.' }, if: -> (user) { user.new_record? || !user.mobile_number.blank? } 上述代码有效,仅在调用model.update(等)时验证新_记录上是否存在手机号码,或者手机号码是否为空 validate

我尝试只在自定义验证方法是新记录或属性在更新时出现时调用它

validates :mobile_number, presence: {
  message: 'Please provide your phone number.'
}, if: -> (user) { user.new_record? || !user.mobile_number.blank? }
上述代码有效,仅在调用model.update(等)时验证新_记录上是否存在手机号码,或者手机号码是否为空

validate :mobile_number_is_unique, if: -> (user) { user.new_record? || !user.mobile_number.blank? }
上述代码不起作用,将在调用model.update(等)时验证新_记录上手机号码的唯一性。 是否有方法将相同的逻辑应用于验证方法,以便在调用model.update(等)时,当手机号码为空时不会调用该方法

mobile\u number\u是用于进一步上下文的唯一方法

# Determines if the mobile number is unique.
def mobile_number_is_unique
  return errors.add(
    :mobile_number, 'Sorry, an account with that phone number already exists.'
  ) unless User.find_by(
    mobile_number: PhonyRails.normalize_number(mobile_number)
  ).nil?
end
更新

实现以下目标的最干净方法:

validates :mobile_number, presence: {
  message: 'Please provide your phone number.'
}, phony_plausible: {
  message: 'Sorry, phone number format not recognized.'
}, uniqueness: {
  message: 'Sorry, an account with that phone number already exists.'
}, if: -> (user) { user.new_record? || !user.mobile_number.blank? }

使用“验证:手机号码”是唯一的方法,包括当前型号上的手机号码,需要将其排除在外才能通过。

您正在检查手机号码是否已存在,包括当前正在编辑的用户的手机号码。您应该能够只使用:

验证:手机号码,唯一性:true

如果您希望使用自定义验证方法,可以使用以下方法排除所选用户:

validate :mobile_number_is_unique

# Determines if the mobile number is unique.
def mobile_number_is_unique
  if new_record? || !mobile_number.blank?
    return errors.add(
      :mobile_number, 'Sorry, an account with that phone number already exists.'
    ) unless User.where(mobile_number: PhonyRails.normalize_number(mobile_number)).where.not(id: id).count == 0
  end
end
旧版本

是的,您可以将if语句移动到
mobile\u number\u is\u unique
方法中

所以会变成这样:

validate :mobile_number_is_unique

# Determines if the mobile number is unique.
def mobile_number_is_unique
  if new_record? || !mobile_number.blank?
    return errors.add(
      :mobile_number, 'Sorry, an account with that phone number already exists.'
    ) unless User.find_by(
      mobile_number: PhonyRails.normalize_number(mobile_number)
    ).nil?
  end
end

您正在检查手机号码是否已经存在,包括您当前编辑的用户的手机号码。您应该能够只使用:

验证:手机号码,唯一性:true

如果您希望使用自定义验证方法,可以使用以下方法排除所选用户:

validate :mobile_number_is_unique

# Determines if the mobile number is unique.
def mobile_number_is_unique
  if new_record? || !mobile_number.blank?
    return errors.add(
      :mobile_number, 'Sorry, an account with that phone number already exists.'
    ) unless User.where(mobile_number: PhonyRails.normalize_number(mobile_number)).where.not(id: id).count == 0
  end
end
旧版本

是的,您可以将if语句移动到
mobile\u number\u is\u unique
方法中

所以会变成这样:

validate :mobile_number_is_unique

# Determines if the mobile number is unique.
def mobile_number_is_unique
  if new_record? || !mobile_number.blank?
    return errors.add(
      :mobile_number, 'Sorry, an account with that phone number already exists.'
    ) unless User.find_by(
      mobile_number: PhonyRails.normalize_number(mobile_number)
    ).nil?
  end
end

若记录中存在手机号码,则只需检查验证。所以你可以使用下面的代码

validate :mobile_number_is_unique


# Determines if the mobile number is unique.
def mobile_number_is_unique
  return unless mobile_number.present?
  errors.add(
    :mobile_number, 'Sorry, an account with that phone number already exists.'
  ) unless User.find_by(
    mobile_number: PhonyRails.normalize_number(mobile_number)
  ).nil?
end

若记录中存在手机号码,则只需检查验证。所以你可以使用下面的代码

validate :mobile_number_is_unique


# Determines if the mobile number is unique.
def mobile_number_is_unique
  return unless mobile_number.present?
  errors.add(
    :mobile_number, 'Sorry, an account with that phone number already exists.'
  ) unless User.find_by(
    mobile_number: PhonyRails.normalize_number(mobile_number)
  ).nil?
end


在方法中移动一个guard子句也不起作用。在rails控制台中更新并设置u=User.first之后,然后检查u.valid?我猜错了。错误消息:{:mobile_number=>[“对不起,该电话号码的帐户已经存在。”]}如果不存在,那么逻辑上我们为什么要对其进行验证?是的,根据我的意见,OP在检查错误的情况proc@Reason更改模型中的代码后是否重新加载控制台?逻辑应该是,如果在更新时存在控制台,则对其运行验证。@原因与private无关,因为它将抛出错误或被调用!所以条件是正确的,那么它是有限的!在方法中移动一个guard子句也不起作用。在rails控制台中更新并设置u=User.first之后,然后检查u.valid?我猜错了。错误消息:{:mobile_number=>[“对不起,该电话号码的帐户已经存在。”]}如果不存在,那么逻辑上我们为什么要对其进行验证?是的,根据我的意见,OP在检查错误的情况proc@Reason更改模型中的代码后是否重新加载控制台?逻辑应该是,如果在更新时存在控制台,则对其运行验证。@原因与private无关,因为它将抛出错误或被调用!所以条件是正确的,那么它是有限的!与@vishal的建议相同。在方法中使用if语句也不起作用。在rails控制台中更新并设置u=User.first之后,然后检查u.valid?我猜错了。错误消息:{:mobile_number=>[“对不起,该电话号码的帐户已经存在。”]}@原因是您正在检查是否已经存在一个手机号码,包括您当前正在编辑的号码。您可以使用
验证:手机号码,唯一性:true
?如果没有,请告诉我,我会再次修改我的答案。是的,我相信这是正确的,验证和验证之间有一个有趣的区别,我很高兴我能够提供帮助。与@vishal的建议相同。在方法中使用if语句也不起作用。在rails控制台中更新并设置u=User.first之后,然后检查u.valid?我猜错了。错误消息:{:mobile_number=>[“对不起,该电话号码的帐户已经存在。”]}@原因是您正在检查是否已经存在一个手机号码,包括您当前正在编辑的号码。您可以使用
验证:手机号码,唯一性:true
?如果没有,请告诉我,我会再次修改我的答案。是的,我相信这是正确的,验证和验证之间有一个有趣的区别,我很高兴我能够提供帮助。