Come aggiornare gli attributi senza convalida


132

Ho un modello con le sue convalide e ho scoperto che non posso aggiornare un attributo senza convalidare l'oggetto prima.

Ho già provato ad aggiungere la on => :createsintassi alla fine di ogni riga di convalida, ma ho ottenuto gli stessi risultati.

Il mio modello di annuncio ha le seguenti convalide:

  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

La mia attività di rake esegue le seguenti operazioni:

  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

Ciò genera tutte le eccezioni di convalida per quel modello, nell'output.

Qualcuno come aggiornare un attributo senza convalidare il modello?

Risposte:


177

UTILIZZA update_attribute anziché update_attributes

Aggiorna un singolo attributo e salva il record senza passare attraverso la normale procedura di convalida.

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

Nota: - 'update_attribute' aggiorna solo un attributo alla volta dal codice indicato in questione, penso che funzionerà per te.


9
Puoi usare save (false) senza validazione
Dzmitry

31
update_attributeè deprecato in Rails 4, FYI. Prova invece a utilizzare a.attributes ({...}). Save (false). Oppure, se non ti interessa (o desideri) eseguire callback, fai il checkout update_column.
Joshua Pinter,

27
Per Rails 4, save(false)non funziona, è necessario utilizzaresave(validate: false)
Tobias Cohen

7
@JoshPinter Hm, update_attributenon sembra essere deprecato in Rails 4.2 (è alias come update_column): api.rubyonrails.org/classes/ActiveRecord/…
Tonči D.

3
@ TončiD. Caspita, hai assolutamente ragione. Sembra che intendessero deprecarlo in 3.2 e rimuoverlo in 4.0 ma poi hanno deciso di invertire la loro decisione poiché non era intercambiabile con update_column. Molto può cambiare in due anni! :) Grazie per segnalarlo. Per saperne di più qui: groups.google.com/forum/?hl=it&fromgroups#!topic/…
Joshua Pinter

185

Puoi fare qualcosa del tipo:

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

13
in realtà è object.save (: validate => false)
Ken Mazaika,

1
Sì. object.save (: validate => false) funziona per me. Mille grazie per il suggerimento!
Robert Reiz,

1
object.attributes = hashè un po 'più in linea con la domanda. Se qualcuno si chiede, update_attributes(hash)si fa semplicemente self.attributes = hash; save.
Lloeki,

1
object.save (false) è tutto ciò che funzionerà se si utilizza Rails 2 e precedenti
stevenspiel

Questo è meglio perché eseguirà comunque i callback che aggiornano i timestamp. L'operazione menziona specificamente l'evitare convalide, non TUTTE le richiamate.
Saneshark,

79

prova ad usare

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

per me va bene


3
questa è la risposta valida con Rails 4, una combinazione di tutti i commenti alla risposta attualmente accettata.
Toobulkeh,


7

Tutta la validazione dal modello viene saltata quando usiamo validate: false

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

Esattamente quello di cui avevo bisogno. Grazie gentile signore!
Ajunpreet Bambrah,

-1

Non dovrebbe essere

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

quindi funziona solo durante la creazione?


L'OP ha dichiarato:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
ho chiuso il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.