Cómo actualizar atributos sin validación


132

Tengo un modelo con sus validaciones, y descubrí que no puedo actualizar un atributo sin validar el objeto antes.

Ya intenté agregar la on => :createsintaxis al final de cada línea de validación, pero obtuve los mismos resultados.

Mi modelo de anuncio tiene las siguientes validaciones:

  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

Mi tarea de rastrillo hace lo siguiente:

  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

Esto arroja todas las excepciones de validación para ese modelo, en la salida.

¿Alguien cómo actualizar un atributo sin validar el modelo?

Respuestas:


177

USE update_attribute en lugar de update_attributes

Actualiza un solo atributo y guarda el registro sin pasar por el procedimiento normal de validación.

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

Nota: - 'update_attribute' actualiza solo un atributo a la vez desde el código proporcionado en cuestión, creo que funcionará para usted.


9
Puede usar guardar (falso) sin validación
Dzmitry

31
update_attributeestá en desuso en Rails 4, FYI. Intente usar a.attributes ({...}). Save (false) en su lugar. O si no le importa (o desea) que se ejecuten devoluciones de llamada, finalice la compra update_column.
Joshua Pinter

27
Para Rails 4, save(false)no funciona, debes usarsave(validate: false)
Tobias Cohen

77
@JoshPinter Hm, update_attributeno parece estar en desuso en Rails 4.2 (tiene el alias de update_column): api.rubyonrails.org/classes/ActiveRecord/…
Tonči D.

3
@ TončiD. Wow, tienes toda la razón. Parece que pretendieron desaprobarlo en 3.2 y eliminarlo en 4.0, pero luego decidieron revertir su decisión ya que no era intercambiable update_column. ¡Mucho puede cambiar en dos años! :) Gracias por mencionarlo. Lea más sobre esto aquí: groups.google.com/forum/?hl=en&fromgroups#!topic/…
Joshua Pinter

185

Puedes hacer algo como:

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

13
en realidad es object.save (: validate => false)
Ken Mazaika

1
Sí. object.save (: validate => false) funciona para mí. Muchas gracias por la pista!
Robert Reiz

1
object.attributes = hashestá un poco más en línea con la pregunta. Si alguien se pregunta, update_attributes(hash)solo lo hace self.attributes = hash; save.
Lloeki

1
object.save (false) es todo lo que funcionará si usa Rails 2 y
versiones

Esto es mejor porque aún ejecutaría las devoluciones de llamada que actualizan las marcas de tiempo. La operación menciona específicamente evitar validaciones, no TODAS las devoluciones de llamada.
saneshark

79

intenta usar

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

funciona para mi


3
Esta es la respuesta válida con Rails 4, una combinación de todos los comentarios a la respuesta actualmente aceptada.
toobulkeh


7

Toda la validación del modelo se omite cuando usamos validate: false

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

Exactamente lo que necesitaba. ¡Gracias buen señor!
Ajunpreet Bambrah

-1

¿No debería ser eso?

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

¿entonces solo funciona durante la creación?


El OP dijo:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
Fui robado el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.