如何在未经验证的情况下更新属性


131

我有一个带有验证的模型,我发现如果不先验证对象就无法更新属性。

我已经尝试on => :create在每个验证行的末尾添加语法,但是得到的结果相同。

我的公告模型具有以下验证:

  validates_presence_of :title
  validates_presence_of :description
  validates_presence_of :announcement_type_id

  validate :validates_publication_date
  validate :validates_start_date
  validate :validates_start_end_dates
  validate :validates_category
  validate :validates_province

  validates_length_of :title, :in => 6..255, :on => :save
  validates_length_of :subtitle, :in => 0..255, :on => :save
  validates_length_of :subtitle, :in => 0..255, :on => :save
  validates_length_of :place, :in => 0..50, :on => :save

  validates_numericality_of :vacants, :greater_than_or_equal_to => 0,  :only_integer => true
  validates_numericality_of :price, :greater_than_or_equal_to => 0,  :only_integer => true

我的瑞克任务执行以下操作:

  task :announcements_expiration => :environment do
    announcements = Announcement.expired

    announcements.each do |a|
      #Gets the user that owns the announcement
      user = User.find(a.user_id)
      puts a.title + '...'

      a.state = 'deactivated'

      if a.update_attributes(:state => a.state)
        puts 'state changed to deactivated'
      else
        a.errors.each do |e|
          puts e
        end

      end
    end

这将在输出中抛出该模型的所有验证异常。

是否有人在不验证模型的情况下如何更新属性?

Answers:


176

使用update_attribute而不是update_attributes

更新单个属性并保存记录,而无需执行正常的验证过程。

if a.update_attribute('state', a.state)

注意:-'update_attribute'一次仅从给出的代码中更新一个属性,我认为它将为您服务。


9
您可以未经验证使用save(false)
Dzmitry 2012年

31
update_attribute在FYI的Rails 4中已弃用。尝试改用a.attributes({...})。save(false)。或者,如果您不希望(或希望)运行回调,请使用checkout update_column
约书亚·品特

27
对于Rails 4,save(false)它不起作用,您必须使用save(validate: false)
Tobias Cohen 2014年

7
@JoshPinter嗯,update_attribute似乎并不在Rails的4.2(它的别名是被弃用update_column):api.rubyonrails.org/classes/ActiveRecord/...
的TončiD.

3
@TončiD。哇,你是绝对正确的。看来他们打算在3.2中弃用它,而在4.0中删除它,但是由于它不能与互换,因此决定撤消他们的决定update_column。两年内可以改变很多!:)感谢您指出。在此处了解更多信息:groups.google.com/forum/?hl=zh
Joshua Pinter

185

您可以执行以下操作:

object.attribute = value
object.save(:validate => false)

13
实际上它的object.save(:validate => false)
Ken Mazaika

1
是的 object.save(:validate => false)对我有用。非常感谢您的提示!
罗伯特·雷兹

1
object.attributes = hash比较符合这个问题。如果有人想知道,update_attributes(hash)它本身只会做self.attributes = hash; save
Lloeki

1
如果使用Rails 2及更低版本,object.save(false)将可以正常工作
stevenspiel 2014年

这样比较好,因为它仍然会执行更新时间戳的回调。op特别提到避免验证,而不是所有回调。
saneshark 2015年

79

尝试使用

@record.assign_attributes({ ... })
@record.save(validate: false)

为我工作


3
这是Rails 4的有效答案,是对当前接受答案的所有注释的组合。
toobulkeh 2015年


7

当我们使用时,会跳过所有来自模型的验证 validate: false

user = User.new(....)
user.save(validate: false)

正是我所需要的。谢谢你,先生!
Ajunpreet Bambrah

-1

那不是吗

validates_length_of :title, :in => 6..255, :on => :create

所以它仅在创建期间有效吗?


OP说:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.