1 ภาพรวมของการตรวจสอบ
นี่คือตัวอย่างของการตรวจสอบที่ง่ายมาก:
class Person < ApplicationRecord
validates :name, presence: true
end
irb> Person.create(name: "John Doe").valid?
=> true
irb> Person.create(name: nil).valid?
=> false
จากตัวอย่างเราสามารถเห็นได้ว่าการตรวจสอบของเราบอกให้เราทราบว่า Person
ของเราไม่ถูกต้องโดยไม่มีแอตทริบิวต์ name
อันที่สอง Person
จะไม่ถูกบันทึกลงในฐานข้อมูล
ก่อนที่เราจะลงรายละเอียดเพิ่มเติมเรามาพูดถึงว่าการตรวจสอบเข้ากับภาพรวมของแอปพลิเคชันของคุณอย่างไร
1.1 ทำไมต้องใช้การตรวจสอบ?
การตรวจสอบถูกใช้เพื่อให้แน่ใจว่าข้อมูลที่ถูกต้องเท่านั้นที่จะถูกบันทึกลงในฐานข้อมูลของคุณ เช่น อาจจะเป็นสิ่งสำคัญต่อแอปพลิเคชันของคุณที่จะต้องให้แน่ใจว่าผู้ใช้ทุกคนให้ที่อยู่อีเมลและที่อยู่สำหรับจดหมายที่ถูกต้อง การตรวจสอบระดับโมเดลเป็นวิธีที่ดีที่สุดในการให้แน่ใจว่าข้อมูลที่ถูกต้องเท่านั้นที่จะถูกบันทึกลงในฐานข้อมูลของคุณ การตรวจสอบระดับโมเดลนี้ไม่ขึ้นกับฐานข้อมูล ไม่สามารถถูกข้ามได้โดยผู้ใช้งาน และสะดวกในการทดสอบและบำรุงรักษา รูปแบบเรลส์มีช่วยเหลือในการตอบสนองความต้องการที่พบบ่อยและช่วยให้คุณสร้างเมธอดการตรวจสอบที่กำหนดเองได้
ยังมีวิธีการตรวจสอบข้อมูลก่อนที่จะถูกบันทึกลงในฐานข้อมูลของคุณอีกหลายวิธี รวมถึงการจำกัดของฐานข้อมูลภายในการตรวจสอบที่รองรับการทดสอบและการบำรุงรักษาที่ยากขึ้น อย่างไรก็ตามหากฐานข้อมูลของคุณถูกใช้งานโดยแอปพลิเคชันอื่น ๆ การใช้บางข้อจำกัดที่ระดับฐานข้อมูลอาจเป็นไอเดียที่ดี นอกจากนี้การตรวจสอบระดับฐานข้อมูลสามารถจัดการกับบางสิ่ง (เช่นความเป็นเอกลักษณ์ในตารางที่ใช้งานอย่างหนัก) ที่ยากต่อการดำเนินการในทางอื่น
การตรวจสอบที่ด้านไคลเอ็นต์อาจเป็นประโยชน์ แต่มักจะไม่เป็นประสิทธิภาพหากใช้คนเดียว หากใช้งานผ่าน JavaScript อาจถูกข้ามได้หาก JavaScript ถูกปิดในเบราว์เซอร์ของผู้ใช้ อย่างไรก็ตามหากใช้ร่วมกับเทคนิคอื่น ๆ การตรวจสอบด้านไคลเอ็นต์สามารถเป็นวิธีที่สะดวกในการให้ผู้ใช้ได้รับข้อมูลตอบกลับทันทีเมื่อใช้งานเว็บไซต์ของคุณ
การตรวจสอบระดับคอนโทรลเลอร์อาจเป็นทางเลือกที่น่าสนใจ แต่มักจะเป็นไปได้ยากและยากในการทดสอบและบำรุงรักษา ในกรณีที่เป็นไปได้ควรพยายามเก็บคอนโทรลเลอร์ของคุณให้เรียบง่ายเสมอ เพราะจะทำให้แอปพลิเคชันของคุณง่ายต่อการใช้งานในระยะยาว
เลือกใช้เหล่านี้ในกรณีที่เฉพาะเจาะจงบางกรณี ทีม Rails เชื่อว่าการตรวจสอบระดับโมเดลเป็นวิธีที่เหมาะสมที่สุดในสถานการณ์ส่วนใหญ่
1.2 เมื่อใดที่การตรวจสอบเกิดขึ้น?
มีออบเจกต์ Active Record 2 ประเภท: ออบเจกต์ที่สอดคล้องกับแถวในฐานข้อมูลของคุณและออบเจกต์ที่ไม่สอดคล้องกับแถวในฐานข้อมูลของคุณ เมื่อคุณสร้างออบเจกต์ใหม่ เช่น โดยใช้เมธอด new
ออบเจกต์นั้นยังไม่ได้เป็นส่วนหนึ่งของฐานข้อมูล หลังจากคุณเรียกใช้ save
บนออบเจกต์นั้น มันจะถูกบันทึกลงในตารางฐานข้อมูลที่เหมาะสม Active Record ใช้เมธอด new_record?
เพื่อตรวจสอบว่าออบเจกต์นั้นอยู่ในฐานข้อมูลแล้วหรือไม่ พิจารณาคลาส Active Record ต่อไปนี้:
ruby
class Person < ApplicationRecord
end
เราสามารถดูวิธีการทำงานของมันได้โดยดูผลลัพธ์ของ bin/rails console
:
irb> p = Person.new(name: "John Doe")
=> #<Person id: nil, name: "John Doe", created_at: nil, updated_at: nil>
irb> p.new_record?
=> true
irb> p.save
=> true
irb> p.new_record?
=> false
การสร้างและบันทึกบันทึกใหม่จะส่งคำสั่ง SQL INSERT
ไปยังฐานข้อมูล การอัปเดตบันทึกที่มีอยู่จะส่งคำสั่ง SQL UPDATE
แทน การตรวจสอบความถูกต้องทั่วไปจะถูกเรียกใช้ก่อนที่จะส่งคำสั่งเหล่านี้ไปยังฐานข้อมูล หากการตรวจสอบความถูกต้องล้มเหลว วัตถุนั้นจะถูกทำเครื่องหมายว่าไม่ถูกต้องและ Active Record จะไม่ดำเนินการ INSERT
หรือ UPDATE
นี้ เพื่อป้องกันการเก็บวัตถุที่ไม่ถูกต้องในฐานข้อมูล คุณสามารถเลือกให้การตรวจสอบความถูกต้องเฉพาะเกิดขึ้นเมื่อวัตถุถูกสร้าง บันทึก หรืออัปเดต
คำเตือน: มีหลายวิธีในการเปลี่ยนสถานะของวัตถุในฐานข้อมูล บางวิธีจะเรียกใช้การตรวจสอบความถูกต้อง แต่บางวิธีไม่เป็นเช่นนั้น นั่นหมายความว่าเป็นไปได้ที่จะบันทึกวัตถุในฐานข้อมูลในสถานะที่ไม่ถูกต้องหากคุณไม่ระมัดระวัง
วิธีการต่อไปนี้จะเรียกใช้การตรวจสอบความถูกต้องและจะบันทึกวัตถุในฐานข้อมูลเฉพาะเมื่อวัตถุถูกต้อง:
create
create!
save
save!
update
update!
เวอร์ชันแบง (เช่น save!
) จะเรียกข้อยกเว้นหากบันทึกไม่ถูกต้อง เวอร์ชันที่ไม่ใช่แบงไม่ได้: save
และ update
จะส่งค่า false
และ create
จะส่งวัตถุ
1.3 การข้ามการตรวจสอบความถูกต้อง
วิธีการต่อไปนี้ข้ามการตรวจสอบความถูกต้องและจะบันทึกวัตถุในฐานข้อมูลไม่ว่าจะถูกต้องหรือไม่ก็ตาม ควรใช้ด้วยความระมัดระวัง
decrement!
decrement_counter
increment!
increment_counter
insert
insert!
insert_all
insert_all!
toggle!
touch
touch_all
update_all
update_attribute
update_column
update_columns
update_counters
upsert
upsert_all
โปรดทราบว่า save
ยังสามารถข้ามการตรวจสอบความถูกต้องได้หากส่ง validate: false
เป็นอาร์กิวเมนต์ วิธีนี้ควรใช้ด้วยความระมัดระวัง
save(validate: false)
1.4 valid?
และ invalid?
ก่อนที่จะบันทึกวัตถุ Active Record เราจะเรียกใช้การตรวจสอบความถูกต้องของคุณ หากการตรวจสอบความถูกต้องนี้สร้างข้อผิดพลาดใด ๆ Rails จะไม่บันทึกวัตถุ
คุณยังสามารถเรียกใช้การตรวจสอบความถูกต้องเหล่านี้เอง valid?
เรียกใช้การตรวจสอบความถูกต้องของคุณ
และคืนค่า true หากไม่พบข้อผิดพลาดใด ๆ ในวัตถุ และ false ในทางกลับกัน
เช่นเห็นได้จากตัวอย่างด้านบน:
class Person < ApplicationRecord
validates :name, presence: true
end
irb> Person.create(name: "John Doe").valid?
=> true
irb> Person.create(name: nil).valid?
=> false
หลังจากที่ Active Record ทำการตรวจสอบความถูกต้องแล้ว ความล้มเหลวใด ๆ สามารถเข้าถึงได้
ผ่านเมธอดตัวอย่าง errors
ซึ่งคืนค่าคอลเลกชันของข้อผิดพลาด
ตามนิยาม วัตถุถูกต้องหากคอลเลกชันนี้เป็นว่างเมื่อทำการตรวจสอบความถูกต้อง
โปรดทราบว่าวัตถุที่สร้างขึ้นด้วย new
จะไม่รายงานข้อผิดพลาด
แม้ว่าจะเป็นไปได้ที่จะไม่ถูกต้องจากด้านเทคนิค เนื่องจากการตรวจสอบความถูกต้องจะถูกเรียกอัตโนมัติ
เมื่อวัตถุถูกบันทึก เช่นด้วยเมธอด create
หรือ save
class Person < ApplicationRecord
validates :name, presence: true
end
irb> p = Person.new
=> #<Person id: nil, name: nil>
irb> p.errors.size
=> 0
irb> p.valid?
=> false
irb> p.errors.objects.first.full_message
=> "Name can’t be blank"
irb> p = Person.create
=> #<Person id: nil, name: nil>
irb> p.errors.objects.first.full_message
=> "Name can’t be blank"
irb> p.save
=> false
irb> p.save!
ActiveRecord::RecordInvalid: Validation failed: Name can’t be blank
irb> Person.create!
ActiveRecord::RecordInvalid: Validation failed: Name can’t be blank
invalid?
เป็นการสลับกันของ valid?
มันจะเรียกใช้การตรวจสอบความถูกต้องของคุณลักษณะต่าง ๆ ในวัตถุ และคืนค่าเป็นจริงถ้าพบข้อผิดพลาดใด ๆ ในวัตถุ และเป็นเท็จในทางกลับกัน
1.5 errors[]
เพื่อตรวจสอบว่าคุณลักษณะใดของวัตถุนั้นถูกต้องหรือไม่ คุณสามารถใช้ errors[:attribute]
ได้ มันจะคืนค่าเป็นอาร์เรย์ของข้อความผิดพลาดทั้งหมดสำหรับ :attribute
หากไม่มีข้อผิดพลาดในคุณลักษณะที่ระบุ มันจะคืนค่าเป็นอาร์เรย์ว่าง
เมธอดนี้มีประโยชน์เฉพาะหลังจากที่การตรวจสอบความถูกต้องได้รันแล้ว เนื่องจากมันจะตรวจสอบเฉพาะคอลเลกชันของข้อผิดพลาดเท่านั้นและไม่เรียกใช้การตรวจสอบความถูกต้องเอง มันแตกต่างจากเมธอด ActiveRecord::Base#invalid?
ที่อธิบายไว้ข้างต้น เนื่องจากมันไม่ตรวจสอบความถูกต้องของวัตถุในทั้งหมด มันเช็คเพียงเพื่อดูว่ามีข้อผิดพลาดที่พบในคุณลักษณะบุคคลของวัตถุหรือไม่
class Person < ApplicationRecord
validates :name, presence: true
end
irb> Person.new.errors[:name].any?
=> false
irb> Person.create.errors[:name].any?
=> true
เราจะพูดถึงข้อผิดพลาดในการตรวจสอบอย่างละเอียดมากขึ้นในส่วน การทำงานกับข้อผิดพลาดในการตรวจสอบ
2 ช่วยในการตรวจสอบความถูกต้อง
Active Record มีเครื่องมือช่วยในการตรวจสอบความถูกต้องที่กำหนดไว้ล่วงหน้าหลายอย่างที่คุณสามารถใช้ได้โดยตรงภายในการกำหนดคลาสของคุณ เครื่องมือเหล่านี้จะให้กฎการตรวจสอบที่เป็นที่นิยม ทุกครั้งที่การตรวจสอบล้มเหลว จะเพิ่มข้อผิดพลาดในคอลเลกชัน errors
ของวัตถุ และนี่เกี่ยวข้องกับคุณลักษณะที่กำลังตรวจสอบ
แต่ละเครื่องมือยอมรับชื่อคุณลักษณะได้ไม่จำกัด ดังนั้นคุณสามารถเพิ่มการตรวจสอบประเภทเดียวกันไปยังคุณลักษณะหลาย ๆ คุณลักษณะได้ด้วยบรรทัดเดียว
ทุกเครื่องมือยอมรับตัวเลือก :on
และ :message
ซึ่งกำหนดเมื่อการตรวจสอบความถูกต้องควรทำงานและข้อความที่ควรเพิ่มในคอลเลกชัน errors
หากการตรวจสอบล้มเหลวตามลำดับ ตัวเลือก :on
รับค่าหนึ่งในค่า :create
หรือ :update
มีข้อความผิดพลาดเริ่มต้นสำหรับเครื่องมือตรวจสอบแต่ละอัน ข้อความเหล่านี้ถูกใช้เมื่อไม่ระบุตัวเลือก :message
มาดูทีละเครื่องมือที่มีอยู่
หากต้องการดูรายการเครื่องมือช่วยเริ่มต้นที่มีอยู่ ดูที่ ActiveModel::Validations::HelperMethods
2.1 acceptance
เมธอดนี้ตรวจสอบว่าช่องทำเครื่องหมายในอินเตอร์เฟซผู้ใช้ถูกทำเครื่องหมายเมื่อส่งแบบฟอร์ม นี่เป็นสิ่งที่ใช้เมื่อผู้ใช้ต้องการยอมรับข้อกำหนดและเงื่อนไขของแอปพลิเคชันของคุณ ยืนยันว่ามีการอ่านข้อความบางส่วน หรือแน่ใจว่ามีความคิดเห็นใด ๆ ที่เกี่ยวข้อง
class Person < ApplicationRecord
validates :terms_of_service, acceptance: true
end
การตรวจสอบนี้จะถูกดำเนินการเฉพาะเมื่อ terms_of_service
ไม่เป็น nil
ข้อความผิดพลาดเริ่มต้นสำหรับเครื่องมือช่วยนี้คือ "ต้องยอมรับ" คุณยังสามารถส่งข้อความที่กำหนดเองผ่านตัวเลือก message
class Person < ApplicationRecord
validates :terms_of_service, acceptance: { message: 'ต้องปฏิบัติตาม' }
end
มันยังสามารถรับตัวเลือก :accept
ซึ่งกำหนดค่าที่ยอมรับที่จะถือว่าถูกต้อง มันเริ่มต้นเป็น ['1', true]
และสามารถเปลี่ยนแปลงได้ง่าย
class Person < ApplicationRecord
validates :terms_of_service, acceptance: { accept: 'yes' }
validates :eula, acceptance: { accept: ['TRUE', 'accepted'] }
end
การตรวจสอบนี้เป็นเฉพาะในเว็บแอปพลิเคชันและ 'การยอมรับ' นี้ไม่จำเป็นต้องบันทึกไว้ในฐานข้อมูลของคุณ หากคุณไม่มีฟิลด์สำหรับมัน เครื่องมือช่วยจะสร้างคุณลักษณะเสมือน หากฟิลด์มีอยู่ในฐานข้อมูลของคุณ ตัวเลือก accept
ต้องถูกตั้งค่าเป็นหรือรวม true
มิฉะนั้นการตรวจสอบจะไม่ทำงาน
2.2 การยืนยัน
คุณควรใช้ตัวช่วยนี้เมื่อคุณมีฟิลด์ข้อความสองอันที่ควรได้รับเนื้อหาที่เหมือนกันอย่างแน่นอน ตัวอย่างเช่น คุณอาจต้องการยืนยันที่อยู่อีเมลหรือรหัสผ่าน การตรวจสอบนี้จะสร้างแอตทริบิวต์เสมือนที่ชื่อของฟิลด์ที่ต้องยืนยันด้วยการเพิ่ม "_confirmation"
class Person < ApplicationRecord
validates :email, confirmation: true
end
ในเทมเพลตของมุมมองของคุณ คุณสามารถใช้สิ่งที่คล้ายกันเช่น
<%= text_field :person, :email %>
<%= text_field :person, :email_confirmation %>
หมายเหตุ: การตรวจสอบนี้จะถูกดำเนินการเฉพาะเมื่อ email_confirmation
ไม่เป็น nil
หากต้องการให้มีการยืนยัน ตรวจสอบให้แน่ใจว่ามีการตรวจสอบความสามารถในแอตทริบิวต์การยืนยัน (เราจะพิจารณา การมีอยู่ ในคู่มือนี้ภายหลัง):
class Person < ApplicationRecord
validates :email, confirmation: true
validates :email_confirmation, presence: true
end
ยังมีตัวเลือก :case_sensitive
ที่คุณสามารถใช้เพื่อกำหนดว่าการจำกัดการยืนยันจะเป็นตัวอักษรตัวใหญ่และตัวเล็กหรือไม่ ตัวเลือกนี้มีค่าเริ่มต้นเป็นจริง
class Person < ApplicationRecord
validates :email, confirmation: { case_sensitive: false }
end
ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวช่วยนี้คือ "ไม่ตรงกับการยืนยัน" คุณยังสามารถส่งข้อความที่กำหนดเองผ่านตัวเลือก message
ได้
โดยทั่วไปเมื่อใช้ตัวตรวจสอบนี้ คุณต้องการรวมกับตัวเลือก :if
เพื่อตรวจสอบเฉพาะฟิลด์ "_confirmation" เมื่อฟิลด์เริ่มต้นเปลี่ยนแปลงและ ไม่ทุกครั้งที่คุณบันทึกบันทึก อ่านเพิ่มเติมเกี่ยวกับ การตรวจสอบเงื่อนไข ในภายหลัง
class Person < ApplicationRecord
validates :email, confirmation: true
validates :email_confirmation, presence: true, if: :email_changed?
end
2.3 การเปรียบเทียบ
การตรวจสอบนี้จะตรวจสอบการเปรียบเทียบระหว่างค่าสองค่าที่เปรียบเทียบได้
class Promotion < ApplicationRecord
validates :end_date, comparison: { greater_than: :start_date }
end
ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวช่วยนี้คือ "การเปรียบเทียบล้มเหลว" คุณยังสามารถส่งข้อความที่กำหนดเองผ่านตัวเลือก message
ได้
ตัวเลือกเหล่านี้ถูกสนับสนุนทั้งหมด:
:greater_than
- ระบุว่าค่าต้องมากกว่าค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องมากกว่า %{count}":greater_than_or_equal_to
- ระบุว่าค่าต้องมากกว่าหรือเท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องมากกว่าหรือเท่ากับ %{count}":equal_to
- ระบุว่าค่าต้องเท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องเท่ากับ %{count}":less_than
- ระบุว่าค่าต้องน้อยกว่าค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องน้อยกว่า %{count}":less_than_or_equal_to
- ระบุว่าค่าต้องน้อยกว่าหรือเท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องน้อยกว่าหรือเท่ากับ %{count}":other_than
- ระบุว่าค่าต้องไม่เท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องไม่เท่ากับ %{count}"
หมายเหตุ: ตัวตรวจสอบต้องการการเปรียบเทียบที่จะให้มีการระบุตัวเลือก แต่ละตัวเลือกยอมรับค่า โปรแกรม หรือสัญลักษณ์ ค่าใดก็ได้ คลาสใดก็ได้ที่รวม Comparable สามารถเปรียบเทียบกันได้
2.4 รูปแบบ
ตัวช่วยนี้ใช้ตรวจสอบค่าของแอตทริบิวต์โดยทดสอบว่ามีความตรงกันกับรูปแบบที่กำหนดโดยใช้ตัวเลือก :with
class Product < ApplicationRecord
validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
message: "อนุญาตเฉพาะตัวอักษรเท่านั้น" }
end
ในทางกลับกัน โดยใช้ตัวเลือก :without
แทน คุณสามารถต้องการให้แอตทริบิวต์ที่ระบุไม่ตรงกับรูปแบบที่กำหนด
ในทั้งสองกรณี ตัวเลือก :with
หรือ :without
ที่ให้มาต้องเป็น regular expression หรือ proc หรือ lambda ที่ส่งคืน regular expression
ข้อความข้อผิดพลาดเริ่มต้นคือ "ไม่ถูกต้อง"
คำเตือน ใช้ \A
และ \z
เพื่อตรงกับจุดเริ่มต้นและจุดสิ้นสุดของสตริง ^
และ $
ตรงกับจุดเริ่มต้น/สิ้นสุดของบรรทัด ด้วยเหตุผลที่ ^
และ $
ถูกใช้ผิดบ่อยครั้ง คุณต้องส่งตัวเลือก multiline: true
ในกรณีที่คุณใช้สองตัวยึดเหล่านี้ใน regular expression ที่ให้มา ในกรณีส่วนใหญ่คุณควรใช้ \A
และ \z
2.5 การรวมเข้า
ตัวช่วยนี้ใช้ตรวจสอบค่าของแอตทริบิวต์โดยตรวจสอบว่ามีอยู่ในชุดที่กำหนด ในความเป็นจริง ชุดนี้สามารถเป็นวัตถุที่สามารถนับได้
class Coffee < ApplicationRecord
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} ไม่ใช่ขนาดที่ถูกต้อง" }
end
ตัวช่วย inclusion
มีตัวเลือก :in
ที่รับชุดค่าที่จะได้รับการยอมรับ ตัวเลือก :in
มีชื่อย่อที่เรียกว่า :within
ที่คุณสามารถใช้เพื่อวัตถุประสงค์เดียวกัน หากคุณต้องการ ตัวอย่างก่อนหน้านี้ใช้ตัวเลือก :message
เพื่อแสดงว่าคุณสามารถรวมค่าของแอตทริบิวต์ได้ สำหรับตัวเลือกเต็มรูปแบบโปรดดูเอกสาร ข้อความ
ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวช่วยนี้คือ "ไม่ได้อยู่ในรายการ"
2.6 การยกเว้น
ข้อกลับของ การรวมเข้า
คือ... การยกเว้น
!
ตัวช่วยนี้ใช้ตรวจสอบค่าของแอตทริบิวต์โดยตรวจสอบว่าไม่ได้รวมอยู่ในชุดที่กำหนด ในความเป็นจริง ชุดนี้สามารถเป็นวัตถุที่สามารถนับได้
class Account < ApplicationRecord
validates :subdomain, exclusion: { in: %w(www us ca jp),
message: "%{value} ถูกสงวนไว้" }
end
ตัวช่วย exclusion
มีตัวเลือก :in
ที่รับชุดค่าที่จะไม่ได้รับการยอมรับสำหรับแอตทริบิวต์ที่ต้องการตรวจสอบ ตัวเลือก :in
มีชื่อย่อที่เรียกว่า :within
ที่คุณสามารถใช้เพื่อวัตถุประสงค์เดียวกัน ตัวอย่างนี้ใช้ตัวเลือก :message
เพื่อแสดงว่าคุณสามารถรวมค่าของแอตทริบิวต์ได้ สำหรับตัวเลือกเต็มรูปแบบของข้อความโปรดดูเอกสาร ข้อความ
ข้อความข้อผิดพลาดเริ่มต้นคือ "ถูกสงวน"
ในกรณีที่ไม่ใช่ enumerable แบบดั้งเดิม (เช่น Array) คุณสามารถให้ proc, lambda หรือสัญลักษณ์ที่คืนค่า enumerable ได้ หาก enumerable เป็นช่วงตัวเลข เวลา หรือวันที่แล้วทดสอบจะดำเนินการด้วย Range#cover?
มิฉะนั้นด้วย include?
เมื่อใช้ proc หรือ lambda ตัวอย่างนี้ผ่านตัวอย่างการตรวจสอบที่ต้องการ
ตัวเลือกการจำกัดความยาวที่เป็นไปได้คือ:
:minimum
- แอตทริบิวต์ต้องมีความยาวไม่น้อยกว่าค่าที่ระบุ:maximum
- แอตทริบิวต์ต้องมีความยาวไม่เกินค่าที่ระบุ:in
(หรือ:within
) - ความยาวของแอตทริบิวต์ต้องอยู่ในช่วงที่กำหนด ค่าสำหรับตัวเลือกนี้ต้องเป็นช่วง:is
- ความยาวของแอตทริบิวต์ต้องเท่ากับค่าที่ระบุ
ข้อความข้อผิดพลาดเริ่มต้นขึ้นอยู่กับประเภทของการตรวจสอบความยาวที่กำลังดำเนินการ คุณสามารถกำหนดข้อความเหล่านี้เองโดยใช้ตัวเลือก :wrong_length
, :too_long
, และ :too_short
และ %{count}
เป็นตัวยึดตำแหน่งสำหรับจำนวนที่สอดคล้องกับการจำกัดความยาวที่ใช้งาน คุณยังสามารถใช้ตัวเลือก :message
เพื่อระบุข้อความข้อผิดพลาด
class Person < ApplicationRecord
validates :bio, length: { maximum: 1000,
too_long: "%{count} ตัวอักษรเป็นค่าสูงสุดที่อนุญาต" }
end
โปรดทราบว่าข้อความข้อผิดพลาดเริ่มต้นเป็นพหูพจน์ (เช่น "สั้นเกินไป (ค่าต่ำสุดคือ %{count} ตัวอักษร)") ดังนั้นเมื่อ :minimum
เป็น 1 คุณควรจัดหาข้อความข้อผิดพลาดที่กำหนดเองหรือใช้ presence: true
แทน และเมื่อ :in
หรือ :within
มีขีดจำกัดต่ำสุดเป็น 1 คุณควรจัดหาข้อความข้อผิดพลาดที่กำหนดเองหรือเรียกใช้ presence
ก่อน length
หมายเหตุ: สามารถใช้ตัวเลือกข้อจำกัดได้เพียงตัวเลือกเดียวนอกเหนือจากตัวเลือก :minimum
และ :maximum
ที่สามารถรวมกันได้
2.7 numericality
ช่วยในการตรวจสอบว่าแอตทริบิวต์ของคุณมีค่าที่เป็นตัวเลขเท่านั้น โดยค่าเริ่มต้นจะตรงกับเครื่องหมายที่เลือกตามด้วยจำนวนเต็มหรือจำนวนทศนิยม
ในการระบุว่าอนุญาตเฉพาะตัวเลขจำนวนเต็มเท่านั้น ให้ตั้งค่า :only_integer
เป็น true จากนั้นจะใช้ regular expression ต่อไปนี้ในการตรวจสอบค่าของแอตทริบิวต์
/\A[+-]?\d+\z/
มิฉะนั้น จะพยายามแปลงค่าเป็นตัวเลขโดยใช้ Float
และ Float
จะถูกแปลงเป็น BigDecimal
โดยใช้ค่าความแม่นยำของคอลัมน์หรือสูงสุด 15 หลัก
class Player < ApplicationRecord
validates :points, numericality: true
validates :games_played, numericality: { only_integer: true }
end
ข้อความข้อผิดพลาดเริ่มต้นสำหรับ :only_integer
คือ "ต้องเป็นจำนวนเต็ม"
นอกเหนือจาก :only_integer
ช่วยในการตรวจสอบค่าที่เป็นตัวเลขเท่านั้น ช่วยให้รับค่าที่เป็นตัวอย่างของ Numeric
และพยายามแปลงค่าถ้าเป็น String
หมายเหตุ: โดยค่าเริ่มต้น numericality
ไม่อนุญาตค่า nil
คุณสามารถใช้ตัวเลือก allow_nil: true
เพื่ออนุญาตให้มี โปรดทราบว่าสำหรับคอลัมน์ Integer
และ Float
สตริงที่ว่างเปล่าจะถูกแปลงเป็น nil
ข้อความข้อผิดพลาดเริ่มต้นเมื่อไม่ระบุตัวเลือกคือ "ไม่ใช่ตัวเลข"
ยังมีตัวเลือกอื่น ๆ ที่สามารถใช้เพื่อเพิ่มข้อจำกัดในค่าที่ยอมรับได้:
:greater_than
- ระบุว่าค่าต้องมากกว่าค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องมากกว่า %{count}":greater_than_or_equal_to
- ระบุว่าค่าต้องมากกว่าหรือเท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องมากกว่าหรือเท่ากับ %{count}":equal_to
- ระบุว่าค่าต้องเท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องเท่ากับ %{count}":less_than
- ระบุว่าค่าต้องน้อยกว่าค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องน้อยกว่า %{count}":less_than_or_equal_to
- ระบุว่าค่าต้องน้อยกว่าหรือเท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องน้อยกว่าหรือเท่ากับ %{count}":other_than
- ระบุว่าค่าต้องไม่เท่ากับค่าที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องไม่เท่ากับ %{count}":in
- ระบุว่าค่าต้องอยู่ในช่วงที่ระบุ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องอยู่ใน %{count}":odd
- ระบุว่าค่าต้องเป็นจำนวนคี่ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องเป็นจำนวนคี่":even
- ระบุว่าค่าต้องเป็นจำนวนคู่ ข้อความข้อผิดพลาดเริ่มต้นสำหรับตัวเลือกนี้คือ "ต้องเป็นจำนวนคู่" ###presence
ฟังก์ชันนี้ใช้ในการตรวจสอบว่าแอตทริบิวต์ที่ระบุไม่เป็นค่าว่าง โดยใช้เมธอด Object#blank?
เพื่อตรวจสอบว่าค่าเป็น nil
หรือสตริงที่ว่างเปล่า กล่าวคือสตริงที่ว่างเปล่าหรือประกอบด้วยช่องว่าง
class Person < ApplicationRecord
validates :name, :login, :email, presence: true
end
หากคุณต้องการให้แน่ใจว่ามีการเชื่อมโยงอยู่ คุณจะต้องทดสอบว่าวัตถุที่เชื่อมโยงกันเองมีอยู่ และไม่ใช่คีย์ต่างประเทศที่ใช้ในการแมปการเชื่อมโยง โดยวิธีนี้จะตรวจสอบไม่เพียงแค่คีย์ต่างประเทศว่าไม่ว่างเปล่าเท่านั้น แต่ยังตรวจสอบว่าวัตถุที่อ้างถึงมีอยู่จริง
class Supplier < ApplicationRecord
has_one :account
validates :account, presence: true
end
เพื่อที่จะตรวจสอบระเบียนที่เชื่อมโยงกันที่จำเป็นต้องมีการตรวจสอบ คุณต้องระบุตัวเลือก :inverse_of
สำหรับการเชื่อมโยง:
class Order < ApplicationRecord
has_many :line_items, inverse_of: :order
end
หมายเหตุ: หากคุณต้องการให้แน่ใจว่าการเชื่อมโยงมีอยู่และถูกต้อง คุณยังต้องใช้ validates_associated
ด้วย อ่านเพิ่มเติมได้ที่ ด้านล่าง
หากคุณตรวจสอบความเป็นมาตรฐานของวัตถุที่เชื่อมโยงผ่านความสัมพันธ์ has_one
หรือ has_many
มันจะตรวจสอบว่าวัตถุไม่ได้เป็น blank?
หรือ marked_for_destruction?
เนื่องจาก false.blank?
เป็นจริง หากคุณต้องการตรวจสอบความเป็นมาตรฐานของฟิลด์บูลีน คุณควรใช้การตรวจสอบดังต่อไปนี้:
# ค่า _ต้อง_ เป็น true หรือ false
validates :boolean_field_name, inclusion: [true, false]
# ค่า _ต้องไม่_ เป็น nil, กล่าวคือ true หรือ false
validates :boolean_field_name, exclusion: [nil]
โดยใช้การตรวจสอบหนึ่งในเหล่านี้ คุณจะรับประกันว่าค่าจะไม่เป็น nil
ซึ่งจะทำให้ได้ค่า NULL
ในกรณีส่วนใหญ่
ข้อความข้อผิดพลาดเริ่มต้นคือ "can’t be blank"
2.8 absence
ฟังก์ชันนี้ใช้ในการตรวจสอบว่าแอตทริบิวต์ที่ระบุไม่มีอยู่ โดยใช้เมธอด Object#present?
เพื่อตรวจสอบว่าค่าไม่ใช่ nil
หรือสตริงที่ว่างเปล่า กล่าวคือสตริงที่ว่างเปล่าหรือประกอบด้วยช่องว่าง
class Person < ApplicationRecord
validates :name, :login, :email, absence: true
end
หากคุณต้องการให้แน่ใจว่าไม่มีการเชื่อมโยงอยู่ คุณจะต้องทดสอบว่าวัตถุที่เชื่อมโยงกันเองไม่มีอยู่ และไม่ใช่คีย์ต่างประเทศที่ใช้ในการแมปการเชื่อมโยง
class LineItem < ApplicationRecord
belongs_to :order
validates :order, absence: true
end
เพื่อที่จะตรวจสอบระเบียนที่เชื่อมโยงกันที่ไม่มีอยู่ คุณต้องระบุตัวเลือก :inverse_of
สำหรับการเชื่อมโยง:
class Order < ApplicationRecord
has_many :line_items, inverse_of: :order
end
หมายเหตุ: หากคุณต้องการให้แน่ใจว่าการเชื่อมโยงมีอยู่และถูกต้อง คุณยังต้องใช้ validates_associated
ด้วย อ่านเพิ่มเติมได้ที่ ด้านล่าง
หากคุณตรวจสอบความเป็นมาตรฐานของวัตถุที่เชื่อมโยงผ่านความสัมพันธ์ has_one
หรือ has_many
มันจะตรวจสอบว่าวัตถุไม่ได้เป็น present?
หรือ marked_for_destruction?
เนื่องจาก false.present?
เป็นเท็จ หากคุณต้องการตรวจสอบความไม่มีอยู่ของฟิลด์บูลีน คุณควรใช้ validates :field_name, exclusion: { in: [true, false] }
ข้อความข้อผิดพลาดเริ่มต้นคือ "must be blank"
2.9 uniqueness
ผู้ช่วยนี้ตรวจสอบค่าของ attribute ว่าเป็นค่าที่ไม่ซ้ำกันก่อนที่วัตถุจะถูกบันทึกลงในฐานข้อมูล
class Account < ApplicationRecord
validates :email, uniqueness: true
end
การตรวจสอบนี้จะเกิดขึ้นโดยการดำเนินการคิวรี SQL เข้าไปยังตารางของโมเดล โดยค้นหาบันทึกที่มีค่าเดียวกันใน attribute นั้น
มีตัวเลือก :scope
ที่คุณสามารถใช้เพื่อระบุหนึ่งหรือหลาย attribute ที่ใช้ในการจำกัดการตรวจสอบความไม่ซ้ำกัน:
class Holiday < ApplicationRecord
validates :name, uniqueness: { scope: :year,
message: "should happen once per year" }
end
คำเตือน. การตรวจสอบนี้ไม่สร้างข้อจำกัดความไม่ซ้ำกันในฐานข้อมูล ดังนั้นอาจเกิดกรณีที่การเชื่อมต่อฐานข้อมูลสองตัวที่แตกต่างกันสร้างบันทึกสองรายการที่มีค่าเดียวกันสำหรับคอลัมน์ที่คุณตั้งให้เป็นค่าที่ไม่ซ้ำกัน หากต้องการหลีกเลี่ยงสถานการณ์ดังกล่าว คุณต้องสร้างดัชนีที่ไม่ซ้ำกันในคอลัมน์นั้นในฐานข้อมูลของคุณ
เพื่อเพิ่มข้อจำกัดความไม่ซ้ำกันในฐานข้อมูลของคุณ ใช้คำสั่ง add_index
ในการเรียกใช้งานและรวมตัวเลือก unique: true
หากคุณต้องการสร้างข้อจำกัดความไม่ซ้ำกันในฐานข้อมูลเพื่อป้องกันการละเมิดที่เป็นไปได้ของการตรวจสอบความไม่ซ้ำกันโดยใช้ตัวเลือก :scope
คุณต้องสร้างดัชนีที่ไม่ซ้ำกันในทั้งสองคอลัมน์ในฐานข้อมูลของคุณ ดู คู่มือ MySQL เพื่อดูรายละเอียดเพิ่มเติมเกี่ยวกับดัชนีหลายคอลัมน์หรือ คู่มือ PostgreSQL เพื่อดูตัวอย่างของข้อจำกัดที่ไม่ซ้ำกันที่อ้างถึงกลุ่มของคอลัมน์
ยังมีตัวเลือก :case_sensitive
ที่คุณสามารถใช้เพื่อกำหนดว่าข้อจำกัดความไม่ซ้ำกันจะเป็นตัวพิมพ์ใหญ่-เล็ก ไม่สนใจตัวพิมพ์ใหญ่-เล็ก หรือเคารพการจัดเรียงของฐานข้อมูลเริ่มต้น ตัวเลือกนี้มีค่าเริ่มต้นเป็นเคารพการจัดเรียงของฐานข้อมูลเริ่มต้น
class Person < ApplicationRecord
validates :name, uniqueness: { case_sensitive: false }
end
คำเตือน. โปรดทราบว่าบางฐานข้อมูลถูกกำหนดค่าให้ดำเนินการค้นหาโดยไม่สนใจตัวพิมพ์ใหญ่-เล็กอยู่แล้ว
มีตัวเลือก :conditions
ที่คุณสามารถระบุเงื่อนไขเพิ่มเติมเป็นเฟรกเมนต์ SQL WHERE
เพื่อจำกัดการค้นหาข้อจำกัดความไม่ซ้ำกัน (เช่น conditions: -> { where(status: 'active') }
)
ข้อความผิดพลาดเริ่มต้นคือ "has already been taken".
ดู validates_uniqueness_of
เพื่อข้อมูลเพิ่มเติม
2.10 validates_associated
คุณควรใช้ผู้ช่วยนี้เมื่อโมเดลของคุณมีความสัมพันธ์ที่ต้องการตรวจสอบเสมอ ทุกครั้งที่คุณพยายามบันทึกวัตถุของคุณ valid?
จะถูกเรียกใช้งานบนวัตถุที่เกี่ยวข้องแต่ละตัว
class Library < ApplicationRecord
has_many :books
validates_associated :books
end
การตรวจสอบนี้จะทำงานกับทุกประเภทของความสัมพันธ์
คำเตือน: อย่าใช้ validates_associated
ทั้งสองด้านของความสัมพันธ์ของคุณ มันจะเรียกใช้งานกันเองในลูปไม่สิ้นสุด
ข้อความผิดพลาดเริ่มต้นสำหรับ validates_associated
คือ "is invalid". โปรดทราบว่าแต่ละวัตถุที่เกี่ยวข้องจะมีคอลเลกชันของข้อผิดพลาดของตัวเอง ข้อผิดพลาดไม่สามารถส่งผ่านไปยังโมเดลที่เรียกใช้งานได้
หมายเหตุ: validates_associated
สามารถใช้ได้เฉพาะกับวัตถุ ActiveRecord เท่านั้น สิ่งที่เรียกใช้ก่อนหน้านี้สามารถใช้กับวัตถุใดก็ได้ที่รวม ActiveModel::Validations
2.11 validates_each
ผู้ช่วยนี้ตรวจสอบ attribute ตามบล็อกที่กำหนด ไม่มีฟังก์ชันการตรวจสอบที่กำหนดไว้ล่วงหน้า คุณควรสร้างฟังก์ชันการตรวจสอบโดยใช้บล็อก และทุก attribute ที่ถูกส่งผ่านไปยัง validates_each
จะถูกทดสอบตามนั้น
ในตัวอย่างต่อไปนี้ เราจะปฏิเสธชื่อและนามสกุลที่ขึ้นต้นด้วยตัวพิมพ์เล็ก
class Person < ApplicationRecord
validates_each :name, :surname do |record, attr, value|
record.errors.add(attr, 'must start with upper case') if /\A[[:lower:]]/.match?(value)
end
end
บล็อกจะรับ record, ชื่อของ attribute และค่าของ attribute
คุณสามารถทำอะไรก็ได้ในบล็อกเพื่อตรวจสอบข้อมูลที่ถูกต้อง หากการตรวจสอบล้มเหลวคุณควรเพิ่มข้อผิดพลาดในโมเดลเพื่อทำให้โมเดลไม่ถูกต้อง
2.12 validates_with
ช่วยให้คลาสเฉพาะสำหรับการตรวจสอบส่ง record ไปยังคลาสที่แยกออกมาเพื่อทำการตรวจสอบ
class GoodnessValidator < ActiveModel::Validator
def validate(record)
if record.first_name == "Evil"
record.errors.add :base, "This person is evil"
end
end
end
class Person < ApplicationRecord
validates_with GoodnessValidator
end
ไม่มีข้อความผิดพลาดเริ่มต้นสำหรับ validates_with
คุณต้องเพิ่มข้อผิดพลาดเองในคลาสตรวจสอบ
หมายเหตุ: ข้อผิดพลาดที่เพิ่มใน record.errors[:base]
เกี่ยวข้องกับสถานะของ record โดยรวม
ในการดำเนินการ validate method คุณต้องยอมรับพารามิเตอร์ record
ในการกำหนดเมธอด ซึ่งเป็น record ที่จะถูกตรวจสอบ
หากคุณต้องการเพิ่มข้อผิดพลาดใน attribute ที่ระบุ ให้ส่งมันเป็นอาร์กิวเมนต์แรก เช่น record.errors.add(:first_name, "please choose another name")
เราจะพูดถึง [validation errors][] ในรายละเอียดเพิ่มเติมในภายหลัง
def validate(record)
if record.some_field != "acceptable"
record.errors.add :some_field, "this field is unacceptable"
end
end
ช่วยเหลือ validates_with
รับคลาสหรือรายการคลาสที่จะใช้สำหรับการตรวจสอบ
class Person < ApplicationRecord
validates_with MyValidator, MyOtherValidator, on: :create
end
เช่นเดียวกับการตรวจสอบอื่น ๆ validates_with
รับ :if
, :unless
และ :on
options หากคุณส่งตัวเลือกอื่น ๆ มันจะส่งตัวเลือกเหล่านั้นไปยังคลาสตรวจสอบเป็น options
:
class GoodnessValidator < ActiveModel::Validator
def validate(record)
if options[:fields].any? { |field| record.send(field) == "Evil" }
record.errors.add :base, "This person is evil"
end
end
end
class Person < ApplicationRecord
validates_with GoodnessValidator, fields: [:first_name, :last_name]
end
โปรดทราบว่า validator จะถูกเริ่มต้น เพียงครั้งเดียว สำหรับไฟล์แอปพลิเคชันทั้งหมด และไม่ใช่ในแต่ละการตรวจสอบ ดังนั้นให้ระมัดระวังในการใช้ตัวแปรอินสแตนซ์ภายใน
หาก validator ของคุณซับซ้อนพอที่คุณต้องการตัวแปรอินสแตนซ์คุณสามารถใช้วัตถุรูบีธร้อยแทนได้ง่าย:
class Person < ApplicationRecord
validate do |person|
GoodnessValidator.new(person).validate
end
end
class GoodnessValidator
def initialize(person)
@person = person
end
def validate
if some_complex_condition_involving_ivars_and_private_methods?
@person.errors.add :base, "This person is evil"
end
end
# ...
end
เราจะพูดถึง custom validations ในภายหลัง
3 Common Validation Options
มีตัวเลือกที่ใช้กันอย่างแพร่หลายที่รองรับโดย validators ที่เราได้กล่าวถึงเพิ่มเติม มาเริ่มต้นกันเลย!
หมายเหตุ: ไม่ใช่ทุกตัวเลือกเหล่านี้รองรับโดย validators ทุกตัว โปรดอ้างอิงเอกสาร API สำหรับ ActiveModel::Validations
โดยใช้เมธอดการตรวจสอบใด ๆ ที่เรากล่าวถึงเพิ่มเติม ยังมีรายการตัวเลือกที่ใช้ร่วมกับ validators ร่วมกัน เราจะพูดถึงเรื่องเหล่านี้ตอนนี้!
:allow_nil
: ข้ามการตรวจสอบหาก attribute เป็นnil
:allow_blank
: ข้ามการตรวจสอบหาก attribute เป็น blank:message
: ระบุข้อความผิดพลาดที่กำหนดเอง:on
: ระบุบริบทที่การตรวจสอบนี้มีผล:strict
: เรียกข้อยกเว้นเมื่อการตรวจสอบล้มเหลว:if
และ:unless
: ระบุเมื่อควรหรือไม่ควรมีการตรวจสอบ ###:allow_nil
ตัวเลือก :allow_nil
จะข้ามการตรวจสอบเมื่อค่าที่กำลังตรวจสอบเป็น nil
.
class Coffee < ApplicationRecord
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} ไม่ใช่ขนาดที่ถูกต้อง" }, allow_nil: true
end
irb> Coffee.create(size: nil).valid?
=> true
irb> Coffee.create(size: "mega").valid?
=> false
สำหรับตัวเลือกเต็มรูปแบบของอาร์กิวเมนต์ข้อความโปรดดูที่ เอกสารข้อความ.
3.1 :allow_blank
ตัวเลือก :allow_blank
คล้ายกับตัวเลือก :allow_nil
ตัวเลือกนี้จะทำให้การตรวจสอบผ่านได้หากค่าของแอตทริบิวต์เป็น blank?
เช่น nil
หรือสตริงที่ว่างเปล่าเป็นต้น
class Topic < ApplicationRecord
validates :title, length: { is: 5 }, allow_blank: true
end
irb> Topic.create(title: "").valid?
=> true
irb> Topic.create(title: nil).valid?
=> true
3.2 :message
เหมือนกับที่คุณเคยเห็นแล้ว ตัวเลือก :message
ช่วยให้คุณระบุข้อความที่จะถูกเพิ่มในคอลเล็กชัน errors
เมื่อการตรวจสอบล้มเหลว หากไม่ใช้ตัวเลือกนี้ Active Record จะใช้ข้อความผิดพลาดเริ่มต้นที่เกี่ยวข้องสำหรับแต่ละช่วยในการตรวจสอบ
ตัวเลือก :message
รับค่าเป็น String
หรือ Proc
ค่า String
ของ :message
สามารถมี %{value}
, %{attribute}
, และ %{model}
ที่อาจมีหรือไม่มีได้ และจะถูกแทนที่โดยอัตโนมัติเมื่อการตรวจสอบล้มเหลว การแทนที่นี้จะถูกทำโดยใช้ i18n gem และตัวยึดต้องตรงกันอย่างเที่ยงตรง ไม่อนุญาตให้มีช่องว่าง
class Person < ApplicationRecord
# ข้อความที่กำหนดแบบคงที่
validates :name, presence: { message: "ต้องระบุ" }
# ข้อความที่มีค่าแอตทริบิวต์แบบไดนามิก ค่า %{value} จะถูกแทนที่
# ด้วยค่าจริงของแอตทริบิวต์ และ %{attribute} และ %{model}
# ก็สามารถใช้ได้
validates :age, numericality: { message: "%{value} ดูเหมือนผิด" }
end
ค่า Proc
ของ :message
รับอาร์กิวเมนต์สองตัว: ออบเจกต์ที่กำลังตรวจสอบ และแฮชที่มีคีย์-ค่าเป็น :model
, :attribute
, และ :value
class Person < ApplicationRecord
validates :username,
uniqueness: {
# object = ออบเจกต์ person ที่กำลังตรวจสอบ
# data = { model: "Person", attribute: "Username", value: <username> }
message: ->(object, data) do
"สวัสดี #{object.name}, #{data[:value]} ถูกใช้งานแล้ว."
end
}
end
3.3 :on
ตัวเลือก :on
ช่วยให้คุณระบุเมื่อการตรวจสอบควรเกิดขึ้น พฤติกรรมเริ่มต้นสำหรับช่วยในการตรวจสอบที่มีอยู่ทั้งหมดคือการทำงานเมื่อบันทึก (ทั้งเมื่อคุณสร้างบันทึกใหม่และเมื่อคุณอัปเดต) หากคุณต้องการเปลี่ยนแปลงคุณสามารถใช้ on: :create
เพื่อให้การตรวจสอบเกิดขึ้นเฉพาะเมื่อสร้างบันทึกใหม่หรือ on: :update
เพื่อให้การตรวจสอบเกิดขึ้นเฉพาะเมื่ออัปเดตบันทึก
class Person < ApplicationRecord
# จะสามารถอัปเดตอีเมลด้วยค่าที่ซ้ำกันได้
validates :email, uniqueness: true, on: :create
# จะสามารถสร้างบันทึกด้วยอายุที่ไม่ใช่ตัวเลขได้
validates :age, numericality: true, on: :update
# ค่าเริ่มต้น (ตรวจสอบทั้งการสร้างและการอัปเดต)
validates :name, presence: true
end
คุณยังสามารถใช้ on:
เพื่อกำหนดบริบทที่กำหนดเองได้ บริบทที่กำหนดเองจะต้องถูกเรียกใช้โดยชื่อของบริบทที่ผ่านมาให้กับ valid?
, invalid?
, หรือ save
class Person < ApplicationRecord
validates :email, uniqueness: true, on: :account_setup
validates :age, numericality: true, on: :account_setup
end
irb> person = Person.new(age: 'สามสิบสาม')
irb> person.valid?
=> true
irb> person.valid?(:account_setup)
=> false
irb> person.errors.messages
=> {:email=>["ถูกใช้ไปแล้ว"], :age=>["ไม่ใช่ตัวเลข"]}
person.valid?(:account_setup)
ทำการตรวจสอบ validations ทั้งสองโดยไม่บันทึก model ลงฐานข้อมูล person.save(context: :account_setup)
ทำการตรวจสอบ person
ใน context account_setup
ก่อนที่จะบันทึก
การส่งอาร์เรย์ของสัญลักษณ์เป็นสิ่งที่ยอมรับได้เช่นกัน
class Book
include ActiveModel::Validations
validates :title, presence: true, on: [:update, :ensure_title]
end
irb> book = Book.new(title: nil)
irb> book.valid?
=> true
irb> book.valid?(:ensure_title)
=> false
irb> book.errors.messages
=> {:title=>["ต้องไม่เป็นค่าว่าง"]}
เมื่อถูกเรียกใช้โดย context ที่ระบุโดยชัดเจน validations จะถูกเรียกใช้สำหรับ context นั้น ๆ รวมถึง validations ที่ไม่มี context
class Person < ApplicationRecord
validates :email, uniqueness: true, on: :account_setup
validates :age, numericality: true, on: :account_setup
validates :name, presence: true
end
irb> person = Person.new
irb> person.valid?(:account_setup)
=> false
irb> person.errors.messages
=> {:email=>["ถูกใช้ไปแล้ว"], :age=>["ไม่ใช่ตัวเลข"], :name=>["ต้องไม่เป็นค่าว่าง"]}
เราจะพิจารณากรณีการใช้งานเพิ่มเติมสำหรับ on:
ในคู่มือของ callbacks
4 Strict Validations
คุณยังสามารถระบุ validations เพื่อให้เป็นเครื่องหมายเข้มและเรียก ActiveModel::StrictValidationFailed
เมื่อวัตถุไม่ถูกต้อง
class Person < ApplicationRecord
validates :name, presence: { strict: true }
end
irb> Person.new.valid?
ActiveModel::StrictValidationFailed: ชื่อต้องไม่เป็นค่าว่าง
ยังมีความสามารถในการส่งข้อยกเว้นที่กำหนดเองไปยังตัวเลือก :strict
ด้วย
class Person < ApplicationRecord
validates :token, presence: true, uniqueness: true, strict: TokenGenerationException
end
irb> Person.new.valid?
TokenGenerationException: โทเค็นต้องไม่เป็นค่าว่าง
5 การตรวจสอบเงื่อนไข
บางครั้งการตรวจสอบวัตถุเฉพาะเมื่อเงื่อนไขที่กำหนดไว้ถูกตรวจสอบ คุณสามารถทำได้โดยใช้ตัวเลือก :if
และ :unless
ซึ่งสามารถรับสัญลักษณ์ Proc
หรือ Array
ได้ คุณสามารถใช้ตัวเลือก :if
เมื่อคุณต้องการระบุเมื่อการตรวจสอบ ควร เกิดขึ้น หรือถ้าคุณต้องการระบุเมื่อการตรวจสอบ ไม่ควร เกิดขึ้น คุณสามารถใช้ตัวเลือก :unless
5.1 การใช้สัญลักษณ์กับ :if
และ :unless
คุณสามารถเชื่อมโยงตัวเลือก :if
และ :unless
กับสัญลักษณ์ที่สอดคล้องกับชื่อของเมธอดที่จะถูกเรียกใช้ก่อนการตรวจสอบ นี่เป็นตัวเลือกที่ใช้มากที่สุด
class Order < ApplicationRecord
validates :card_number, presence: true, if: :paid_with_card?
def paid_with_card?
payment_type == "card"
end
end
5.2 การใช้ Proc
กับ :if
และ :unless
คุณสามารถเชื่อมโยง :if
และ :unless
กับอ็อบเจกต์ Proc
ซึ่งจะถูกเรียกใช้ การใช้ Proc
ให้คุณสามารถเขียนเงื่อนไขแบบอินไลน์แทนที่จะเป็นเมธอดแยกต่างหาก ตัวเลือกนี้เหมาะสำหรับบรรทัดเดียว
class Account < ApplicationRecord
validates :password, confirmation: true,
unless: Proc.new { |a| a.password.blank? }
end
เนื่องจาก lambda
เป็นชนิดของ Proc
คุณยังสามารถใช้เงื่อนไขแบบอินไลน์โดยใช้ไวยากรณ์ที่สั้นลง
validates :password, confirmation: true, unless: -> { password.blank? }
6 การจัดกลุ่มการตรวจสอบเงื่อนไข
บางครั้งการมีการตรวจสอบหลาย ๆ รายการที่ใช้เงื่อนไขเดียวกันจะเป็นประโยชน์ คุณสามารถทำได้ง่ายๆ โดยใช้ with_options
ruby
class User < ApplicationRecord
with_options if: :is_admin? do |admin|
admin.validates :password, length: { minimum: 10 }
admin.validates :email, presence: true
end
end
การตรวจสอบความถูกต้องทั้งหมดภายในบล็อก with_options
จะผ่านเงื่อนไข if: :is_admin?
โดยอัตโนมัติ
6.1 การรวมเงื่อนไขการตรวจสอบ
ในกรณีอื่น ๆ เมื่อมีเงื่อนไขหลายอย่างที่กำหนดว่าการตรวจสอบความถูกต้องควรเกิดขึ้นหรือไม่ สามารถใช้ Array
ได้ นอกจากนี้คุณยังสามารถใช้ทั้ง :if
และ :unless
ในการตรวจสอบเดียวกันได้
class Computer < ApplicationRecord
validates :mouse, presence: true,
if: [Proc.new { |c| c.market.retail? }, :desktop?],
unless: Proc.new { |c| c.trackpad.present? }
end
การตรวจสอบเกิดขึ้นเฉพาะเมื่อทุกเงื่อนไข :if
และไม่มีเงื่อนไข :unless
ที่ประเมินค่าเป็น true
7 การทำการตรวจสอบที่กำหนดเอง
เมื่อช่วยตรวจสอบที่มีอยู่ไม่เพียงพอสำหรับความต้องการของคุณ คุณสามารถเขียนตัวตรวจสอบหรือเมธอดการตรวจสอบที่คุณต้องการได้ตามต้องการ
7.1 ตัวตรวจสอบที่กำหนดเอง
ตัวตรวจสอบที่กำหนดเองเป็นคลาสที่สืบทอดมาจาก ActiveModel::Validator
คลาสเหล่านี้ต้องประมวลผลเมธอด validate
ซึ่งรับอาร์กิวเมนต์เป็นเร็คคอร์ดและดำเนินการตรวจสอบบนเร็คคอร์ด ตัวตรวจสอบที่กำหนดเองจะถูกเรียกใช้โดยใช้เมธอด validates_with
class MyValidator < ActiveModel::Validator
def validate(record)
unless record.name.start_with? 'X'
record.errors.add :name, "กรุณาใส่ชื่อที่ขึ้นต้นด้วย X!"
end
end
end
class Person < ApplicationRecord
validates_with MyValidator
end
วิธีที่ง่ายที่สุดในการเพิ่มตัวตรวจสอบที่กำหนดเองสำหรับการตรวจสอบแต่ละแอตทริบิวต์คือ ActiveModel::EachValidator
ในกรณีนี้ คลาสตัวตรวจสอบที่กำหนดเองต้องประมวลผลเมธอด validate_each
ซึ่งรับอาร์กิวเมนต์สามตัว: เร็คคอร์ด แอตทริบิวต์ที่จะตรวจสอบ และค่าของแอตทริบิวต์ในเรคคอร์ดที่ผ่านมา
class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless URI::MailTo::EMAIL_REGEXP.match?(value)
record.errors.add attribute, (options[:message] || "ไม่ใช่อีเมล")
end
end
end
class Person < ApplicationRecord
validates :email, presence: true, email: true
end
ตามที่แสดงในตัวอย่าง คุณยังสามารถรวมการตรวจสอบมาตรฐานกับตัวตรวจสอบที่กำหนดเองของคุณได้เช่นกัน
7.2 เมธอดที่กำหนดเอง
คุณยังสามารถสร้างเมธอดที่ตรวจสอบสถานะของโมเดลของคุณและเพิ่มข้อผิดพลาดในคอลเลกชัน errors
เมื่อไม่ถูกต้อง คุณจะต้องลงทะเบียนเมธอดเหล่านี้โดยใช้เมธอดคลาส validate
โดยส่งสัญลักษณ์สำหรับชื่อเมธอดการตรวจสอบ
คุณสามารถส่งสัญลักษณ์มากกว่าหนึ่งสัญลักษณ์สำหรับแต่ละเมธอดคลาส และการตรวจสอบที่เกี่ยวข้องจะถูกเรียกใช้ในลำดับเดียวกันกับที่ลงทะเบียน
เมื่อคุณเรียกใช้เมธอด valid?
จะตรวจสอบว่าคอลเลกชัน errors
ว่างเปล่า ดังนั้นเมธอดการตรวจสอบที่กำหนดเองของคุณควรเพิ่มข้อผิดพลาดในนั้นเมื่อคุณต้องการให้การตรวจสอบล้มเหลว:
class Invoice < ApplicationRecord
validate :expiration_date_cannot_be_in_the_past,
:discount_cannot_be_greater_than_total_value
def expiration_date_cannot_be_in_the_past
if expiration_date.present? && expiration_date < Date.today
errors.add(:expiration_date, "ไม่สามารถเป็นวันที่ผ่านมาได้")
end
end
def discount_cannot_be_greater_than_total_value
if discount > total_value
errors.add(:discount, "ไม่สามารถมีส่วนลดมากกว่ามูลค่ารวมได้")
end
end
end
ตามค่าเริ่มต้น การตรวจสอบเช่นนี้จะทำงานทุกครั้งที่คุณเรียกใช้ valid?
หรือบันทึกวัตถุ แต่คุณยังสามารถควบคุมเมื่อจะเรียกใช้การตรวจสอบที่กำหนดเองเหล่านี้ได้โดยให้ตัวเลือก :on
ให้กับเมธอด validate
ด้วย :create
หรือ :update
```ruby
class Invoice < ApplicationRecord
validate :active_customer, on: :create
def active_customer errors.add(:customer_id, "ไม่ได้เปิดใช้งาน") unless customer.active? end end ```
ดูส่วนด้านบนสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ :on
。
7.3 การระบุ Validators
หากคุณต้องการหา Validators ทั้งหมดสำหรับอ็อบเจ็กต์ที่กำหนดให้ คุณสามารถใช้ validators
ได้
ตัวอย่างเช่น หากเรามีโมเดลต่อไปนี้ที่ใช้ Validator ที่กำหนดเองและ Validator ที่มีอยู่แล้ว:
class Person < ApplicationRecord
validates :name, presence: true, on: :create
validates :email, format: URI::MailTo::EMAIL_REGEXP
validates_with MyOtherValidator, strict: true
end
เราสามารถใช้ validators
บนโมเดล "Person" เพื่อแสดงรายการ Validators ทั้งหมด หรือตรวจสอบฟิลด์ที่ระบุโดยใช้ validators_on
ได้
irb> Person.validators
#=> [#<ActiveRecord::Validations::PresenceValidator:0x10b2f2158
@attributes=[:name], @options={:on=>:create}>,
#<MyOtherValidatorValidator:0x10b2f17d0
@attributes=[:name], @options={:strict=>true}>,
#<ActiveModel::Validations::FormatValidator:0x10b2f0f10
@attributes=[:email],
@options={:with=>URI::MailTo::EMAIL_REGEXP}>]
#<MyOtherValidator:0x10b2f0948 @options={:strict=>true}>]
irb> Person.validators_on(:name)
#=> [#<ActiveModel::Validations::PresenceValidator:0x10b2f2158
@attributes=[:name], @options={on: :create}>]
8 การทำงานกับ Validation Errors
เมื่อใช้ valid?
และ invalid?
เราจะได้รับสถานะสรุปเกี่ยวกับความถูกต้อง อย่างไรก็ตามคุณสามารถตรวจสอบข้อผิดพลาดแต่ละข้อได้โดยใช้เมธอดต่างๆ จากคอลเลกชัน errors
ต่อไปนี้คือรายการเมธอดที่ใช้บ่อยที่สุด โปรดอ้างอิงที่เอกสาร ActiveModel::Errors
เพื่อดูรายการเมธอดทั้งหมดที่มีอยู่
8.1 errors
เป็นทางเข้าที่คุณสามารถเข้าถึงรายละเอียดต่างๆ ของแต่ละข้อผิดพลาด
เมื่อเรียกใช้งานจะได้รับอินสแตนซ์ของคลาส ActiveModel::Errors
ที่มีข้อผิดพลาดทั้งหมด แต่ละข้อผิดพลาดจะถูกแทนที่ด้วยอ็อบเจ็กต์ ActiveModel::Error
class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
irb> person = Person.new
irb> person.valid?
=> false
irb> person.errors.full_messages
=> ["Name can’t be blank", "Name is too short (minimum is 3 characters)"]
irb> person = Person.new(name: "John Doe")
irb> person.valid?
=> true
irb> person.errors.full_messages
=> []
irb> person = Person.new
irb> person.valid?
=> false
irb> person.errors.first.details
=> {:error=>:too_short, :count=>3}
8.2 errors[]
ใช้ errors[]
เมื่อคุณต้องการตรวจสอบข้อความข้อผิดพลาดสำหรับแอตทริบิวต์ที่ระบุ มันจะคืนอาร์เรย์ของสตริงที่มีข้อความข้อผิดพลาดทั้งหมดสำหรับแอตทริบิวต์ที่กำหนด แต่ละสตริงจะมีข้อความข้อผิดพลาดหนึ่งข้อความ หากไม่มีข้อผิดพลาดที่เกี่ยวข้องกับแอตทริบิวต์ จะคืนอาร์เรย์ว่างเปล่า
class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
irb> person = Person.new(name: "John Doe")
irb> person.valid?
=> true
irb> person.errors[:name]
=> []
irb> person = Person.new(name: "JD")
irb> person.valid?
=> false
irb> person.errors[:name]
=> ["is too short (minimum is 3 characters)"]
irb> person = Person.new
irb> person.valid?
=> false
irb> person.errors[:name]
=> ["can’t be blank", "is too short (minimum is 3 characters)"]
8.3 errors.where
และ Error Object
บางครั้งเราอาจต้องการข้อมูลเพิ่มเติมเกี่ยวกับแต่ละข้อผิดพลาดนอกเหนือจากข้อความข้อผิดพลาด แต่ละข้อผิดพลาดจะถูกแคปซูลเป็นอ็อบเจ็กต์ ActiveModel::Error
และเมธอด where
เป็นวิธีที่ใช้บ่อยที่สุดในการเข้าถึง
where
จะคืนอาร์เรย์ของอ็อบเจ็กต์ข้อผิดพลาดที่ผ่านการกรองตามเงื่อนไขต่างๆ
class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
เราสามารถกรองเฉพาะ attribute
เท่านั้นโดยส่งมันเป็นพารามิเตอร์แรกไปที่ errors.where(:attr)
พารามิเตอร์ที่สองใช้สำหรับกรอง type
ของข้อผิดพลาดที่เราต้องการโดยเรียกใช้ errors.where(:attr, :type)
```irb
irb> person = Person.new
irb> person.valid?
=> false
irb> person.errors.where(:name) => [ ... ] # ข้อผิดพลาดทั้งหมดสำหรับ attribute :name
irb> person.errors.where(:name, :too_short) => [ ... ] # ข้อผิดพลาด :too_short สำหรับ attribute :name ```
สุดท้ายเราสามารถกรองโดยใช้ options
ที่อาจมีอยู่ในวัตถุข้อผิดพลาดประเภทที่กำหนดไว้
irb> person = Person.new
irb> person.valid?
=> false
irb> person.errors.where(:name, :too_short, minimum: 3)
=> [ ... ] # ข้อผิดพลาดทั้งหมดของชื่อที่สั้นเกินไปและค่าต่ำสุดคือ 2
คุณสามารถอ่านข้อมูลต่าง ๆ จากวัตถุข้อผิดพลาดเหล่านี้ได้:
irb> error = person.errors.where(:name).last
irb> error.attribute
=> :name
irb> error.type
=> :too_short
irb> error.options[:count]
=> 3
คุณยังสามารถสร้างข้อผิดพลาดได้:
irb> error.message
=> "is too short (minimum is 3 characters)"
irb> error.full_message
=> "Name is too short (minimum is 3 characters)"
เมธอด full_message
สร้างข้อความที่ใช้งานง่ายมากขึ้น โดยเติมชื่อแอตทริบิวต์ที่เป็นตัวพิมพ์ใหญ่ไว้ด้านหน้า (หากต้องการกำหนดรูปแบบที่ full_message
ใช้ โปรดดูที่ คู่มือ I18n.)
8.4 errors.add
เมธอด add
สร้างวัตถุข้อผิดพลาดโดยใช้ attribute
และ type
ของข้อผิดพลาด รวมถึงแอตทริบิวต์เพิ่มเติมที่เป็นไปได้ นี่เป็นวิธีที่ดีในการเขียนตัวตรวจสอบของคุณเอง เนื่องจากมันช่วยให้คุณกำหนดสถานการณ์ข้อผิดพลาดที่เฉพาะเจาะจงได้
class Person < ApplicationRecord
validate do |person|
errors.add :name, :too_plain, message: "is not cool enough"
end
end
irb> person = Person.create
irb> person.errors.where(:name).first.type
=> :too_plain
irb> person.errors.where(:name).first.full_message
=> "Name is not cool enough"
8.5 errors[:base]
คุณสามารถเพิ่มข้อผิดพลาดที่เกี่ยวข้องกับสถานะของวัตถุโดยรวมแทนที่เกี่ยวข้องกับแอตทริบิวต์เฉพาะ ในการทำเช่นนี้คุณต้องใช้ :base
เป็นแอตทริบิวต์เมื่อเพิ่มข้อผิดพลาดใหม่
class Person < ApplicationRecord
validate do |person|
errors.add :base, :invalid, message: "This person is invalid because ..."
end
end
irb> person = Person.create
irb> person.errors.where(:base).first.full_message
=> "This person is invalid because ..."
8.6 errors.size
เมธอด size
คืนค่าจำนวนข้อผิดพลาดทั้งหมดสำหรับวัตถุ
class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
irb> person = Person.new
irb> person.valid?
=> false
irb> person.errors.size
=> 2
irb> person = Person.new(name: "Andrea", email: "[email protected]")
irb> person.valid?
=> true
irb> person.errors.size
=> 0
8.7 errors.clear
เมธอด clear
ใช้เมื่อคุณต้องการล้างคอลเลกชัน errors
อย่างตั้งใจ แน่นอนว่าการเรียกใช้ errors.clear
กับวัตถุที่ไม่ถูกต้องจะไม่ทำให้มันถูกต้อง: คอลเลกชัน errors
จะว่างเปล่าตอนนี้ แต่ครั้งต่อไปที่คุณเรียกใช้ valid?
หรือเมธอดใด ๆ ที่พยายามบันทึกวัตถุนี้ลงในฐานข้อมูล การตรวจสอบจะเริ่มทำงานอีกครั้ง หากการตรวจสอบใด ๆ ล้มเหลว คอลเลกชัน errors
จะเต็มอีกครั้ง
class Person < ApplicationRecord
validates :name, presence: true, length: { minimum: 3 }
end
irb> person = Person.new
irb> person.valid?
=> false
irb> person.errors.empty?
=> false
irb> person.errors.clear
irb> person.errors.empty?
=> true
irb> person.save
=> false
irb> person.errors.empty?
=> false
9 แสดงข้อผิดพลาดการตรวจสอบในมุมมอง
เมื่อคุณสร้างโมเดลและเพิ่มการตรวจสอบหากโมเดลนั้นถูกสร้างผ่านแบบฟอร์มเว็บ คุณอาจต้องการแสดงข้อความข้อผิดพลาดเมื่อการตรวจสอบหนึ่งในนั้นล้มเหลว
เนื่องจากแอปพลิเคชันแต่ละตัวจัดการเรื่องนี้ได้ต่างกัน ดังนั้น Rails ไม่รวมเครื่องมือช่วยในการสร้างข้อความเหล่านี้โดยตรง อย่างไรก็ตาม เนื่องจากมีจำนวนมากของเมธอดที่ Rails ให้คุณใช้สื่อสารกับการตรวจสอบความถูกต้องทั่วไป คุณสามารถสร้างของคุณเองได้ นอกจากนี้ เมื่อสร้าง scaffold Rails จะใส่ ERB เข้าไปใน _form.html.erb
ที่เกิดขึ้นที่แสดงรายการข้อผิดพลาดทั้งหมดบนโมเดลนั้น
ถ้าเรามีโมเดลที่ถูกบันทึกในตัวแปรอินสแตนซ์ที่ชื่อ @article
มันจะมีลักษณะดังนี้:
<% if @article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@article.errors.count, "error") %> ไม่อนุญาตให้บันทึกบทความนี้:</h2>
<ul>
<% @article.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
นอกจากนี้ หากคุณใช้ช่วยในการสร้างฟอร์มของ Rails เมื่อเกิดข้อผิดพลาดในการตรวจสอบความถูกต้องบนฟิลด์ มันจะสร้าง <div>
เพิ่มเติมรอบการป้อนข้อมูล
<div class="field_with_errors">
<input id="article_title" name="article[title]" size="30" type="text" value="">
</div>
คุณสามารถกำหนดสไตล์ของ div นี้ได้ตามต้องการ ตัวอย่างของ scaffold เริ่มต้นที่ Rails สร้าง เช่น เพิ่มกฎ CSS ดังนี้:
.field_with_errors {
padding: 2px;
background-color: red;
display: table;
}
นี้หมายความว่าฟิลด์ใดก็ตามที่มีข้อผิดพลาดจะมีเส้นขอบสีแดงขนาด 2 พิกเซล
ข้อเสนอแนะ
คุณสามารถช่วยปรับปรุงคุณภาพของคู่มือนี้ได้
กรุณาช่วยเพิ่มเติมหากพบข้อผิดพลาดหรือข้อผิดพลาดทางความจริง เพื่อเริ่มต้นคุณสามารถอ่านส่วน การสนับสนุนเอกสาร ของเราได้
คุณอาจพบเนื้อหาที่ไม่สมบูรณ์หรือเนื้อหาที่ไม่ได้อัปเดต กรุณาเพิ่มเอกสารที่ขาดหายไปสำหรับเนื้อหาหลัก โปรดตรวจสอบ Edge Guides ก่อนเพื่อตรวจสอบ ว่าปัญหาได้รับการแก้ไขหรือไม่ในสาขาหลัก ตรวจสอบ คู่มือแนวทาง Ruby on Rails เพื่อดูรูปแบบและกฎเกณฑ์
หากคุณพบข้อผิดพลาดแต่ไม่สามารถแก้ไขได้เอง กรุณา เปิดปัญหา.
และสุดท้าย การสนทนาใด ๆ เกี่ยวกับ Ruby on Rails เอกสารยินดีต้อนรับที่สุดใน เว็บบอร์ดอย่างเป็นทางการของ Ruby on Rails.