วิธีอัปเดตแอตทริบิวต์โดยไม่ต้องตรวจสอบความถูกต้อง


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
คุณสามารถใช้บันทึก (เท็จ) โดยไม่ต้องตรวจสอบความถูกต้อง
Dzmitry

31
update_attributeเลิกใช้แล้วใน Rails 4, FYI ลองใช้ a.attributes ({... }) บันทึก (false) แทน หรือถ้าคุณไม่ดูแล (หรือต้องการ) update_columnเรียกกลับที่จะทำงานชำระเงิน
Joshua Pinter

27
สำหรับ Rails 4 save(false)ไม่ได้ผลคุณต้องใช้save(validate: false)
Tobias Cohen

7
@JoshPinter อืม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=th&fromgroups#!topic/…
Joshua Pinter

185

คุณสามารถทำสิ่งต่างๆเช่น:

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

13
จริงๆแล้ว object.save (: validate => false)
Ken Mazaika

1
อ๋อ object.save (: validate => false) ใช้ได้กับฉัน ขอบคุณมากสำหรับคำใบ้!
Robert Reiz

1
object.attributes = hashเป็นอีกเล็กน้อยที่สอดคล้องกับคำถาม ถ้าใครสงสัยตัวเองเพียงไม่update_attributes(hash) self.attributes = hash; save
Lloeki

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หากคุณต้องการอัปเดตแอตทริบิวต์หลายรายการ
Zach Colon

7

การตรวจสอบความถูกต้องจากแบบจำลองทั้งหมดจะถูกข้ามไปเมื่อเราใช้ validate: false

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

สิ่งที่ฉันต้องการ ขอบคุณครับท่าน!
Ajunpreet Bambrah

-1

ไม่ควรอย่างนั้น

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

จึงใช้ได้เฉพาะในระหว่างการสร้าง?


OP กล่าวว่า:I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
iwasrobbed
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.