假設我有一個PhoneNumber
多態模型。許多不同的型號可以have_many
phone_numbers。在前端的形式可以從模型到模型略有不同,但說我有一個用戶表單,允許這樣的電話號碼:Rails驗證has_many與集合中其他對象的關聯
用戶:
first phone: ___________
second phone: __________
third phone: ___________
用戶模型
has_many
phone_numbers和
accepts_nested_attributes
也適用於他們。假設我有要求必須按順序填寫電話。
我假設這意味着將所有字段提交爲空字符串並允許服務器進行驗證。但是如何知道一個PhoneNumber
是否單獨?
例如,如果我提交這種形式:
用戶:
first phone: ___________
second phone: 123-456-7890
third phone: 123-456-7890
應該有看起來像這樣的錯誤:
second phone: 123-456-7890 "error: cannot add phone number when 1st number is blank"
或者,如果我有一個更復雜的形式提交:
用戶:
first phone: ___________
second phone: 123-456-7890 "error: cannot add phone number when 1st number is blank"
third phone: 123-456-7890
fourth phone: ___________
fifth phone: 123-456-7890 "error: cannot add phone number when 4th number is blank"
sixth phone: 123-456-7890
什麼是處理這個最高貴的方式?發送空字符串到服務器並解析它們對我來說似乎很骯髒。這裏是代碼,我到目前爲止有:
class User < ActiveRecord::Base
has_many :phone_numbers, as: :callable
validate :phones_cant_be_incorrect_order
private
def phones_cant_be_incorrect_order
return unless phone_numbers.size > 1
intentional_phone_numbers.each.with_index do |_phone, i|
previous_number = i.ordinalize
errors.add(
:"phone_numbers.number",
"can't add phone number when #{previous_number} number is blank"
) unless previous_number_present?(phone_numbers, i)
end
end
# Parse out empty strings
# Example: If only first_phone was filled out, delete all other empty strings.
def intentional_phone_numbers
last_number_present = phone_numbers.reverse.find { |x| x.number.present? }
right_index = phone_numbers.index(last_number_present)
bad = phone_numbers[(right_index + 1)..-1]
self.phone_numbers = phone_numbers - bad
end
def previous_number_present?(array, index)
return true if index.zero?
array[index - 1].number.present?
end
end
這就是代碼很多隻是爲了確保沒有被提交失靈。當然有更好的方法?