Cara memperbarui atribut tanpa validasi

132

Saya punya model dengan validasinya, dan saya tahu bahwa saya tidak dapat memperbarui atribut tanpa memvalidasi objek sebelumnya.

Saya sudah mencoba menambahkan on => :createsintaks di akhir setiap baris validasi, tetapi saya mendapatkan hasil yang sama.

Model pengumuman saya memiliki validasi berikut:

  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

Tugas menyapu saya melakukan hal berikut:

  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

Ini melempar semua pengecualian validasi untuk model itu, dalam output.

Adakah yang bisa memperbarui atribut tanpa memvalidasi model?

Brian Roisentul
sumber

Jawaban:

177

USE update_attribute alih-alih update_attributes

Memperbarui atribut tunggal dan menyimpan catatan tanpa melalui prosedur validasi normal.

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

Catatan: - 'update_attribute' memperbarui hanya satu atribut pada satu waktu dari kode yang diberikan saya pikir itu akan bekerja untuk Anda.

Salil
sumber
9
Anda dapat menggunakan save (false) tanpa validasi
Dzmitry
31
update_attributeditinggalkan dalam Rails 4, FYI. Coba gunakan a.attributes ({...}). Save (false). Atau jika Anda tidak peduli (atau ingin) callback dijalankan, checkout update_column.
Joshua Pinter
27
Untuk Rails 4, save(false)tidak berfungsi, Anda harus menggunakansave(validate: false)
Tobias Cohen
7
@JoshPinter Hm, update_attributetampaknya tidak dicela dalam Rails 4.2 (alias alias update_column): api.rubyonrails.org/classes/ActiveRecord/…
Tonči D.
3
@ TončiD. Wow, Anda benar sekali. Sepertinya mereka bermaksud untuk mencabutnya di 3.2 dan menghapusnya di 4.0 tetapi kemudian memutuskan untuk membalikkan keputusan mereka karena tidak dapat dipertukarkan dengan update_column. Banyak yang bisa berubah dalam dua tahun! :) Terima kasih telah menunjukkannya. Baca lebih lanjut di sini: groups.google.com/forum/?hl=id&fromgroups#!topic/…
Joshua Pinter
185

Anda dapat melakukan sesuatu seperti:

object.attribute = value
object.save(:validate => false)
Olivier Grimard
sumber
13
sebenarnya object.save (: validate => false)
Ken Mazaika
1
Ya. object.save (: validate => false) bekerja untuk saya. Terima kasih banyak atas petunjuknya!
Robert Reiz
1
object.attributes = hashsedikit lebih sesuai dengan pertanyaan. Jika ada yang bertanya-tanya, update_attributes(hash)itu sendirilah yang terjadi self.attributes = hash; save.
Lloeki
1
object.save (false) adalah semua yang akan berfungsi jika menggunakan Rails 2 ke bawah
stevenspiel
Ini lebih baik karena masih akan menjalankan panggilan balik yang memperbarui stempel waktu. Op secara khusus menyebutkan menghindari validasi, bukan SEMUA panggilan balik.
saneshark
79

coba gunakan

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

bekerja untukku

res
sumber
3
ini adalah jawaban yang valid dengan Rails 4, kombinasi dari semua komentar dengan jawaban yang saat ini diterima.
toobulkeh
33

Anda dapat menggunakan:

a.update_column :state, a.state

Periksa: http://apidock.com/rails/ActiveRecord/Persistence/update_column

Memperbarui atribut tunggal objek, tanpa memanggil save.

William Wong Garay
sumber
6
Ini adalah pendekatan terbaik jika Anda ingin melewati validasi dan panggilan balik. Ada juga update_columnsjika Anda ingin memperbarui beberapa atribut.
Zach Colon
7

Semua validasi dari model dilewati saat kami menggunakan validate: false

user = User.new(....)
user.save(validate: false)
MZaragoza
sumber
Apa yang saya butuhkan. Terima kasih, Tuan!
Ajunpreet Bambrah
-1

Bukankah seharusnya begitu

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

jadi itu hanya berfungsi saat buat?

Saifis
sumber
OP mengatakan:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
iwasrobbed