【问题标题】:Single virtual attribute definition for multiple fields多个字段的单个虚拟属性定义
【发布时间】:2014-02-17 04:12:26
【问题描述】:

我想知道是否有办法设置一个虚拟属性,以便它可以处理多个字段/变量。

基本上,我的模型中有几个不同的整数列(收入、税收),对于每个列,我需要检查表单何时提交,并删除非法字符,我通过设置虚拟属性和使用tr 去除字符。

def flexible_income
  income
end

def flexible_income=(income)
  self.income = income.tr('$ ,', '') unless income.blank?
end

然后我在控制器中设置强参数:

params.required(:tax).permit(:flexible_income, :flexible_taxes)

问题是我有很多字段(不仅仅是我上面列出的两个),所以对于每个字段,(其中许多只需要检查完全相同的非法字符)我必须使用一个新的virtual 属性,基本上只是重复相同的代码:

def flexible_taxes
  taxes
end

def flexible_taxes=(taxes)
  self.taxes = taxes.tr('$ ,', '') unless taxes.blank?
end

有没有办法为许多不同的字段设置一个共同的共享属性,同时仍然能够设置强参数?

【问题讨论】:

    标签: ruby-on-rails ruby virtual-attribute


    【解决方案1】:

    您始终可以使用元编程来动态生成所有这些重复代码。

    module Flexible
      FLEXIBLE_ATTRIBUTES.each do |attr|
        define_method("flexible_#{attr}") do
          self.send(attr)
        end
    
        define_method("flexible_#{attr}=") do |val|
          self.send("#{attr}=", val.tr('$ ,', '')) unless val.blank?
        end  
    
      end
    end
    

    现在在你的类中包含这个模块并定义FLEXIBLE_ATTRIBUTES

    class MyModel
      FLEXIBLE_ATTRIBUTES = [:income, :taxes] #......
      include Flexible
    end
    

    现在我还没有测试过这段代码,但它应该能以最少的重复性完成您所寻找的工作。它还将灵活的方法创建逻辑分离到模型本身之外。如果需要,它还允许您在其他类中重用此模块。

    【讨论】:

      【解决方案2】:

      您可以利用 ruby​​ 的元编程define_method

      为那些喜欢的列列表定义虚拟属性

      ['income','taxes'...].each do |attr|
          define_method("flexible_#{attr}") do |arg|
            eval "#{attr}"
          end
      
          define_method("flexible_#{attr}=") do |arg|
            eval "self.#{attr} = #{arg}.tr('$ ,', '') unless #{arg}.blank?"
          end 
      end
      

      参考:

      https://rubymonk.com/learning/books/2-metaprogramming-ruby/chapters/25-dynamic-methods/lessons/72-define-method

      http://apidock.com/ruby/Module/define_method

      http://apidock.com/ruby/Kernel/eval

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多