如何在没有验证的情况下更新属性

Posted

技术标签:

【中文标题】如何在没有验证的情况下更新属性【英文标题】:How to update attributes without validation 【发布时间】:2011-03-01 05:43:06 【问题描述】:

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

我已经尝试在每个验证行的末尾添加 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

我的 rake 任务执行以下操作:

  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

这会在输出中引发该模型的所有验证异常。

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

【问题讨论】:

【参考方案1】:

你可以这样做:

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

【讨论】:

其实它的 object.save(:validate => false) object.attributes = hash 更符合这个问题。如果有人想知道,update_attributes(hash) 本身只是 self.attributes = hash; save object.save(false) 是使用 Rails 2 及以下版本的所有功能 这样更好,因为它仍然会执行更新时间戳的回调。该操作特别提到避免验证,而不是所有回调。 通过这样做,下一个开发人员也更清楚明确不需要验证【参考方案2】:

使用update_attribute 而不是update_attributes

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

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

注意:-“update_attribute”一次只更新一个属性,我认为它对你有用。

【讨论】:

无需验证即可使用 save(false) update_attribute 在 Rails 4 中被弃用,仅供参考。尝试使用 a.attributes( ... ).save(false) 代替。或者,如果您不关心(或不希望)运行回调,请查看 update_column 对于 Rails 4,save(false) 不起作用,您必须使用 save(validate: false) @JoshPinter Hm, update_attribute 在 Rails 4.2 中似乎没有被弃用(别名为 update_column):api.rubyonrails.org/classes/ActiveRecord/… @TončiD。哇,你完全正确。看起来他们打算在 3.2 中弃用它并在 4.0 中删除它,但后来决定撤销他们的决定,因为它不能与 update_column 互换。两年可以改变很多! :) 感谢您指出。在此处阅读更多信息:groups.google.com/forum/?hl=en&fromgroups#!topic/…【参考方案3】:

尝试使用

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

为我工作

【讨论】:

这是 Rails 4 的有效答案,是当前接受答案的所有 cmets 的组合。 @record.tap |r| r.assign_attributes( ... ) .save(validate: false) 如果您愿意,只需一行代码即可。【参考方案4】:

你可以使用:

a.update_column :state, a.state

检查:http://apidock.com/rails/ActiveRecord/Persistence/update_column

更新对象的单个属性,而不调用 save。

【讨论】:

如果您想跳过验证和回调,这是最好的方法。如果您要更新多个属性,还有update_columns【参考方案5】:

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

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

【讨论】:

【参考方案6】:

不应该是这样的

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

所以它只在创建期间有效?

【讨论】:

操作员说:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.

以上是关于如何在没有验证的情况下更新属性的主要内容,如果未能解决你的问题,请参考以下文章

蜂巢:如何在不更新的情况下处理 scd 类型 2

如何在 Shiro 中更新已验证主题的主体

如何在没有 Laravel 尝试将其保存到数据库的情况下在 Eloquent 模型中使用受保护的属性

如何在没有交叉验证的情况下运行网格搜索?

如何在没有基本 http 身份验证的情况下强制 MockitoJUnitRunner 失败?

如何在没有身份验证的情况下创建 JWT 令牌