Rails4重构模型make DRY

时间:2015-11-18 12:08:27

标签: ruby-on-rails ruby-on-rails-4

我尝试优化以下会计模型类,并有两个问题:

1)如何用更优雅的方法替换多个属性设置器?

2)有没有比replace_comma_with_dot方法中的if条件更好的方法

class Accounting < ActiveRecord::Base

  validates :share_ksk, :central_office, :limit_value, :fix_disagio,
            presence: true, numericality: { less_than: 999.99, greater_than_or_equal_to: 0.00 },
            format: { with: /\d*\.\d{0,2}$/, multiline: true, message: I18n.t('accounting.two_digits_after_decimal_point')}

  def share_ksk=(number)
    replace_comma_with_dot(number)
    super
  end

  def central_office=(number)
    replace_comma_with_dot(number)
    super
  end

  def limit_value=(number)
    replace_comma_with_dot(number)
    super
  end

  def fix_disagio=(number)
    replace_comma_with_dot(number)
    super
  end

  def replace_comma_with_dot(number)
    if number.is_a? String
      number.sub!(",", ".")
    elsif number.is_a? Float
      number
    else
      ""
    end
  end

end

用户Pardeep建议我尝试用define_method替换我的getter:

  [:share_ksk=, :central_office=, :limit_value=, :fix_disagio=].each do |method_name|
    self.class.send :define_method, method_name do |number|
      replace_comma_with_dot(number)
      super
    end
  end

我缺少什么?

2 个答案:

答案 0 :(得分:3)

您可以使用define_method动态定义方法,您可以提供更多信息here

您可以使用此

更新replace_comma_with_dot
def replace_comma_with_dot(number)
  return number.sub!(",", ".") if number.is_a? String
  return number if number.is_a? Float
  ""
end

答案 1 :(得分:1)

我没有在模型中使用方法,而是提取功能并将其附加到StringInteger类:

#lib/ext/string.rb
class String
  def replace_comma_with_dot
    number.sub!(",",".") #Ruby automatically returns so no need to use return
  end
end

这 - 如果您的numberstring,则可以执行以下操作:

number = "67,90"
number.replace_comma_with_dot

要在应用中使用此功能,设置者都可以。您可以按如下方式实现您的功能:

 def fix_disagio=(number)
    self[:fix_disagio] = number.replace_comma_with_dot
 end

你的更新没问题,除非我自己回​​避它,因为它会造成不需要的膨胀。

当你从数据库中提取时,我正在寻找一种设置属性的方法,但后来我意识到如果你每次调用模型时都必须设置它,那么肯定会出现问题。

我个人会考虑在db级别更改此内容,如果不这样做,您可能可以使用某种localization来确定是否需要dot或{ {1}}。

这里有一个很好的答案,主张adding to the ActiveRecord::Base class

comma