Як оновити атрибути без перевірки


132

У мене є модель з її валідацією, і я з’ясував, що я не можу оновити атрибут без попередньої перевірки об'єкта.

Я вже намагався додати on => :createсинтаксис в кінці кожного рядка перевірки, але отримав ті самі результати.

Моя модель оголошення має такі перевірки:

  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

Моє завдання граблі виконує наступне:

  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

Це викидає всі винятки для перевірки для цієї моделі у висновку.

Хтось може оновити атрибут без перевірки моделі?

Відповіді:


177

ВИКОРИСТИТИ update_attribute замість update_attributes

Оновляється один атрибут і зберігається запис, не проходячи звичайну процедуру перевірки.

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

Примітка: - 'update_attribute' оновлення лише одного атрибуту одночасно з коду, заданого питанням, я думаю, він буде працювати для вас.


9
Ви можете використовувати save (false) без підтвердження
Дмитрий

31
update_attributeзастаріла в Rails 4, FYI. Спробуйте скористатися a.attributes ({...}). Save (false). Або якщо вам не байдуже (або хочете) запускати зворотні дзвінки, оформити замовлення update_column.
Джошуа Пінтер

27
Для Rails 4 save(false)не працює, ви повинні використовуватиsave(validate: false)
Tobias Cohen,

7
@JoshPinter Hm, update_attributeздається, не застаріло в Rails 4.2 (це псевдонім як update_column): api.rubyonrails.org/classes/ActiveRecord/…
Tonči D.

3
@ TončiD. Нічого собі, ви абсолютно праві. Схоже, вони мали намір знецінити його в 3.2 та видалити в 4.0, але потім вирішили змінити своє рішення, оскільки воно не було взаємозамінним update_column. Багато що може змінитися за два роки! :) Дякуємо, що вказали на це. Детальніше про це читайте тут: groups.google.com/forum/?hl=uk&fromgroups#!topic/…
Джошуа Пінтер

185

Ви можете зробити щось на кшталт:

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

13
власне його object.save (: валіда = = false)
Кен Мазайка

1
Так. object.save (: validate => false) працює для мене. Велике спасибі за підказку!
Роберт Рейз

1
object.attributes = hashтрохи більше відповідає питанню. Якщо хтось дивується, той update_attributes(hash)просто робить self.attributes = hash; save.
Льоекі

1
object.save (false) - це все, що буде працювати, якщо використовувати Rails 2 і нижче
stevenspiel

Це краще, оскільки воно все одно виконуватиме зворотні дзвінки, що оновлюють часові мітки. Спеціаліст спеціально зазначає уникати перевірок, а не ВСІ зворотні дзвінки.
saneshark

79

спробуйте використовувати

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

працює для мене


3
це дійсна відповідь з Rails 4, поєднання всіх коментарів до прийнятої відповіді.
toobulkeh

33

Йо може використовувати:

a.update_column :state, a.state

Перевірте: http://apidock.com/rails/ActiveRecord/Persistence/update_column

Оновлення одного атрибута об'єкта, не викликаючи збереження.


6
Це найкращий підхід, якщо ви хочете пропустити як перевірки, так і зворотні дзвінки. Є також, update_columnsякщо ви хочете оновити кілька атрибутів.
Зак Колон

7

Усі перевірки з моделі пропускаються, коли ми використовуємо validate: false

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

Саме те, що мені було потрібно. Дякую, добрий пане!
Ajunpreet Bambrah

-1

Не повинно бути цього

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

так це працює лише під час створення?


В ОП сказали:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
вручали
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.