如何在没有验证的情况下更新属性
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.
以上是关于如何在没有验证的情况下更新属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有 Laravel 尝试将其保存到数据库的情况下在 Eloquent 模型中使用受保护的属性