So aktualisieren Sie Attribute ohne Validierung


131

Ich habe ein Modell mit seinen Validierungen und habe festgestellt, dass ich ein Attribut nicht aktualisieren kann, ohne das Objekt zuvor zu validieren.

Ich habe bereits versucht, on => :createam Ende jeder Validierungszeile eine Syntax hinzuzufügen , aber ich habe die gleichen Ergebnisse erhalten.

Mein Ankündigungsmodell hat folgende Validierungen:

  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

Meine Rechenaufgabe erledigt Folgendes:

  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

Dadurch werden alle Validierungsausnahmen für dieses Modell in der Ausgabe ausgelöst.

Kann jemand ein Attribut aktualisieren, ohne das Modell zu validieren?

Antworten:


176

USE update_attribute statt update_attributes

Aktualisiert ein einzelnes Attribut und speichert den Datensatz, ohne das normale Validierungsverfahren durchlaufen zu haben.

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

Hinweis: - 'update_attribute' aktualisiert jeweils nur ein Attribut aus dem fraglichen Code. Ich denke, es wird für Sie funktionieren.


9
Sie können save (false) ohne Validierung verwenden
Dzmitry

31
update_attributeist in Rails 4, FYI, veraltet. Versuchen Sie stattdessen, a.attributes ({...}). Save (false) zu verwenden. Oder wenn Sie keine Rückrufe ausführen möchten (oder möchten), checken Sie aus update_column.
Joshua Pinter

27
Für Rails 4, save(false)funktioniert nicht, müssen Sie verwendensave(validate: false)
Tobias Cohen

7
@JoshPinter Hm, update_attributescheint in Rails 4.2 nicht veraltet zu sein (es wird als Alias ​​bezeichnet update_column): api.rubyonrails.org/classes/ActiveRecord/…
Tonči D.

3
@ TončiD. Wow, du bist absolut richtig. Es sieht so aus, als wollten sie es in 3.2 verwerfen und in 4.0 entfernen, entschieden sich dann aber, ihre Entscheidung umzukehren, da es nicht austauschbar war mit update_column. In zwei Jahren kann sich viel ändern! :) Danke, dass du darauf hingewiesen hast. Lesen Sie hier mehr darüber: groups.google.com/forum/?hl=de&fromgroups#!topic/…
Joshua Pinter

185

Sie können so etwas tun wie:

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

13
eigentlich sein object.save (: validate => false)
Ken Mazaika

1
Ja. object.save (: validate => false) funktioniert bei mir. Vielen Dank für den Hinweis!
Robert Reiz

1
object.attributes = hashist ein bisschen mehr im Einklang mit der Frage. Wenn sich jemand wundert, update_attributes(hash)tut er es nur self.attributes = hash; save.
Lloeki

1
object.save (false) ist alles, was bei Verwendung von Rails 2 und darunter
funktioniert

Dies ist besser, da weiterhin die Rückrufe ausgeführt werden, mit denen Zeitstempel aktualisiert werden. In der Operation wird ausdrücklich erwähnt, dass Validierungen vermieden werden und nicht ALLE Rückrufe.
Saneshark

79

versuchen Sie es mit

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

funktioniert bei mir


3
Dies ist die gültige Antwort mit Rails 4, einer Kombination aller Kommentare zur aktuell akzeptierten Antwort.
Toobulkeh


7

Die gesamte Validierung des Modells wird bei Verwendung übersprungen validate: false

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

Genau das, was ich brauchte. Ich danke Ihnen lieber Herr!
Ajunpreet Bambrah

-1

Sollte das nicht sein

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

also funktioniert es nur beim erstellen?


Das OP sagte:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
iwasrobbed
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.