Rails:仅在创建时进行验证,或在字段不为空时进行更新

Jam*_*mie 30 ruby ruby-on-rails rails-activerecord

如果字段不为空,我如何限制Rails验证仅检查创建OR?我正在为我正在处理的应用程序创建一个用户设置页面,问题是,当使用表单提供的参数进行更新时,只有在存在密码和密码确认时才会保存设置.我希望这些密码字段在创建时验证,无论如何,但仅在提供时更新.

cri*_*ian 48

如果要允许空值,请使用:allow_blank with validates.

class Topic < ActiveRecord::Base
  validates :title, length: { is: 5 }, allow_blank: true
end
Run Code Online (Sandbox Code Playgroud)

如果只想在create 验证,请使用on with validates.

class Topic < ActiveRecord::Base
  validates :email, uniqueness: true, on: :create
end
Run Code Online (Sandbox Code Playgroud)

为了掩盖你的情况:

class Topic
  validates :email, presence: true, if: :should_validate?

  def should_validate?
    new_record? || email.present?
  end
end
Run Code Online (Sandbox Code Playgroud)


Jam*_*mie 12

事实证明这比我想象的要简单一些.我将表单输入名称从password和更改password_confirmationnew_passwordnew_password_confirmation.我使用以下行在我的模型中为这些值添加了临时访问器:

attr_accessor :new_password, :new_password_confirmation
Run Code Online (Sandbox Code Playgroud)

我实现了一个password_changed?定义如下的方法:

def password_changed?
    !new_password.blank?
end
Run Code Online (Sandbox Code Playgroud)

最后,我将验证更改为:

validates :new_password, presence: true, confirmation: true, length: { in: 6..20 }, on: :create
validates :new_password, presence: true, confirmation: true, length: { in: 6..20 }, on: :update, if: :password_changed?
validates :new_password_confirmation, presence: true, on: :create
validates :new_password_confirmation, presence: true, on: :update, if: :password_changed?
Run Code Online (Sandbox Code Playgroud)

我很肯定有一个更好的方法来做到这一点(这不是很干)但是现在,它有效.改进的答案仍然非常受欢迎.


小智 7

没有必要更改字段名称,将足以替换:password_changed?:password_digest_changed?您的代码.

validates :password, presence: true, confirmation: true, length: { in: 6..20 }, on: :create
validates :password, presence: true, confirmation: true, length: { in: 6..20 }, on: :update, if: :password_digest_changed?
validates :password_confirmation, presence: true, on: :create
validates :password_confirmation, presence: true, on: :update, if: :password_digest_changed?
Run Code Online (Sandbox Code Playgroud)


San*_*ket 6

请试试

validates :<attributes>, if: Proc.new{|obj| obj.new_record? || !obj.<attribute>.blank? }
Run Code Online (Sandbox Code Playgroud)

或添加自定义方法名称而不是属性名称.

  • 我会使用lambda而不是proc:` - >(obj){obj.new_record?|| ......}` (2认同)