検証なしで属性を更新する方法


132

検証されたモデルがあり、オブジェクトを検証しないと属性を更新できないことがわかりました。

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

これにより、そのモデルのすべての検証例外が出力にスローされます。

モデルを検証せずに属性を更新する方法はありますか?

回答:


177

update_attributesの代わりにupdate_attributeを使用

単一の属性を更新し、通常の検証手順を実行せずにレコードを保存します。

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

注:-「update_attribute」は、問題のコードから一度に1つの属性のみを更新します。


9
検証なしでsave(false)を使用できます
Dzmitry

31
update_attributeRails 4、FYIでは非推奨です。代わりにa.attributes({...})。save(false)を使用してみてください。または、コールバックの実行を気にしない(または望まない)場合は、checkoutを使用しupdate_columnます。
Joshua Pinter

27
Rails 4がsave(false)機能しない場合は、使用する必要がありますsave(validate: false)
Tobias Cohen

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。2年でたくさん変わる!:)それを指摘してくれてありがとう。詳しくは、groups.google.com
Joshua Pinter

185

次のようなことができます:

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

13
実際にはそのobject.save(:validate => false)
マザイカケン

1
うん。object.save(:validate => false)は私のために働きます。ヒントをどうもありがとう!
Robert Reiz

1
object.attributes = hashもう少し質問に沿っています。誰かが不思議に思ったとしても、update_attributes(hash)それ自体は単にそうしself.attributes = hash; saveます。
Lloeki 2014

1
object.save(false)は、Rails 2以下を使用している場合に機能するすべてです
stevenspiel

タイムスタンプを更新するコールバックを実行するため、これはより良い方法です。opは、すべてのコールバックではなく、検証の回避について具体的に言及しています。
saneshark 2015

79

使ってみる

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

私のために働く


3
これは、現在受け入れられている回答に対するすべてのコメントの組み合わせであるRails 4の有効な回答です。
toobulkeh


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.
。–
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.