假设我有一个PhoneNumber
多态模型。许多不同的模型可以have_many
phone_numbers。前端的表单可能因模型而略有不同,但是我说有一个用户表单允许这样的电话号码:
用户:
first phone: ___________
second phone: __________
third phone: ___________
<小时/> 用户模型
has_many
电话号码和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
这是一大堆代码,只是为了确保没有任何内容无序提交。当然有更好的方法吗?
答案 0 :(得分:0)
电话号码的重要性是什么? 如果您只想省略空字符串的字段,请尝试https://github.com/rubiety/nilify_blanks
我不确定为什么要首先在用户模型中验证电话号码。为什么不在他们所属的模型中验证它们呢?