Como atualizar atributos sem validação


132

Eu tenho um modelo com suas validações e descobri que não posso atualizar um atributo sem validar o objeto antes.

Eu já tentei adicionar on => :createsintaxe no final de cada linha de validação, mas obtive os mesmos resultados.

Meu modelo de anúncio tem as seguintes validações:

  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

Minha tarefa de rake faz o seguinte:

  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

Isso lança todas as exceções de validação para esse modelo, na saída.

Alguém como atualizar um atributo sem validar o modelo?

Respostas:


177

USE update_attribute em vez de update_attributes

Atualiza um único atributo e salva o registro sem passar pelo procedimento de validação normal.

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

Nota: - 'update_attribute' atualiza apenas um atributo de cada vez do código fornecido em questão, acho que funcionará para você.


9
Você pode usar save (false) sem validação
Dzmitry

31
update_attributefoi descontinuado no Rails 4, FYI. Tente usar a.attributes ({...}). Save (false). Ou se você não se importa (ou deseja) que retornos de chamada sejam executados, faça o checkout update_column.
Joshua Pinter

27
Para Rails 4, save(false)não funciona, você deve usarsave(validate: false)
Tobias Cohen

7
@JoshPinter Hm, update_attributenão parece ser preterido em trilhos 4.2 (que é alias como update_column): api.rubyonrails.org/classes/ActiveRecord/...
Tonči D.

3
@ TončiD. Uau, você está absolutamente correto. Parece que eles pretendiam descontinuá-lo no 3.2 e removê-lo no 4.0, mas decidiram reverter sua decisão, pois não era intercambiável update_column. Muita coisa pode mudar em dois anos! :) Obrigado por apontar isso. Leia mais sobre o assunto aqui: groups.google.com/forum/?hl=pt_BR&fromgroups#!topic/…
Joshua Pinter

185

Você pode fazer algo como:

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

13
na verdade, a sua object.save (: validate => false)
Ken Mazaika

1
Sim. object.save (: validate => false) funciona para mim. Muito obrigado pela dica!
Robert Reiz

1
object.attributes = hashestá um pouco mais alinhado com a pergunta. Se alguém se pergunta, update_attributes(hash)ele próprio simplesmente faz self.attributes = hash; save.
Lloeki 29/04

1
object.save (false) é tudo o que vai funcionar se usando Rails 2 e abaixo
stevenspiel

Isso é melhor porque ainda executaria os retornos de chamada que atualizam os carimbos de data / hora. O op menciona especificamente evitar validações, não TODOS os retornos de chamada.
precisa saber é

79

tente usar

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

funciona para mim


3
esta é a resposta válida no Rails 4, uma combinação de todos os comentários para a resposta atualmente aceita.
toobulkeh



-1

Isso não deveria ser

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

então só funciona durante a criação?


O OP disse:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
iwasrobbed
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.