问题描述
我有以下看起来很丑陋的红宝石方法,我想对其进行重构并降低其复杂性。
sp.Value = Template ?? (object)DBNull.Value;
任何帮助将不胜感激。谢谢!
解决方法
您可以按以下方式重新组织计算。如有必要,当然可以对各种验证进行重新排序。
def validate(**kwargs)
validate_values_are_strings(**kwargs)
validate_max_lengths(**kwargs)
validate_amount(kwargs[:amount])
validate_max_key_lengths(**kwargs)
validate_email_pattern(kwargs[:email])
end
def validate_values_are_strings(**kwargs)
kwargs.each do |k,v|
raise Sith::ProcessingError,"value of #{k} should be of type String" unless v.is_a? String
end
end
def validate_max_lengths(**kwargs)
k,v = { id: 24,info: 100,first_name: 60,email: 50 }.find do |k,v|
kwargs[k].length > v
end
raise Sith::ProcessingError,"#{k.to_s} length should be less than or equal to #{v}" unless k.nil?
end
def validate_amount(amount)
raise Sith::ProcessingError,"amount should contain digits with upto 2 decimal places" unless
Sith::AMOUNT_REGEX.match?(amount)
end
def validate_max_key_lengths(**kwargs)
raise SithError,"key length should be less than equal to 255" if
[:key1,:key2,:key3].map { |k| kwargs[k].length }.max > 255
end
def validate_email_pattern(email)
raise Sith::ProcessingError,"Invalid Email" unless
Sith::EMAIL_REGEX.match?(email)
end
假设:
kwargs =
{ id: '23',info: '99',first_name: '59',email: 'hank@some_url.com',amount: '2.63',key1: 'cow',key2: 'chicken',key3: 'goat' }
让我们研究其中一些方法的简化。
def validate_values_are_strings(**kwargs)
kwargs.each do |k,v|
raise "value of #{k} should be of type String" unless v.is_a? String
end
end
validate_values_are_strings(**kwargs)
#=> nil (no errors)
validate_values_are_strings(**(kwargs.merge(email: 7)))
#=> RuntimeError (value of email should be of type String)
def validate_max_key_lengths(**kwargs)
raise "key length should be less than equal to 255" if
[:key1,:key3].map { |k| kwargs[k].length }.max > 255
end
validate_max_key_lengths(**kwargs)
#=> nil (no errors)
validate_max_key_lengths(**(kwargs.merge(key2: 'a'*256)))
#=> RuntimeError (key length should be less than equal to 255)
def validate_amount(amount)
raise "amount should contain digits with upto 2 decimal places" unless
/\A\d+(?:\.\d{1,2})?\z/.match?(amount)
end
validate_amount(kwargs[:amount])
#=> nil (no errors)
validate_amount("2.634")
#=> RuntimeError (amount should contain digits with upto 2 decimal places)
,
如果这是Ruby on Rails,我建议使用validations而不是自定义检查并引发异常。这需要制作一个小模型。
class Sith
include ActiveModel::Model
attr_accessor :id,:info,:first_name,:email,:amount,:keys
validates :id,length: { maximum: 25 }
validates :info,length: { maximum: 100 }
validates :first_name,length: { maximum: 60 }
validates :email,length: { maximum: 50 },format: { with: URI::MailTo::EMAIL_REGEXP }
validate :validate_amount_decimal_places
validate :validate_keys
private def validate_amount_decimal_places
if amount != amount.round(2)
errors.add(:amount,"amount should contain digits with upto 2 decimal places")
end
end
private def validate_keys
errors.add(:keys,"there can be,at most,5 keys") if keys.size > 5
if keys.any? { |key| key.length >= 255 }
errors.add(:keys,"keys must be shorter than 255 characters")
end
end
end
请注意,我将各个key1,key2,key3参数组合到一个键数组中。
现在您可以输入Sith
并检查其是否有效。
sith = Sith.new(kwargs)
if !sith.valid?
...
end
如果您想使用例外,请使用Strict Validations。
validates :id,length: { maximum: 25,strict: Sith::ProcessingError }
但是,这些“验证”中的许多似乎都是不必要的,甚至可能是禁止的。为什么要限制某人的电子邮件的长度?
,$ java -version
java version "14.0.2" 2020-07-14
Java(TM) SE Runtime Environment (build 14.0.2+12-46)
Java HotSpot(TM) 64-Bit Server VM (build 14.0.2+12-46,mixed mode,sharing)