2

複数のフィールド/変数を処理できるように仮想属性を設定する方法があるかどうか疑問に思っています。

基本的に、モデルにはいくつかの異なる整数列 (収入、税金) があり、それぞれについて、フォームが送信されたときに確認し、無効な文字を削除する必要があります。これは、仮想属性を設定し、削除するために使用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)

問題は、私が多くのフィールド (上にリストした 2 つ以外) を持っているため、それらのフィールドのそれぞれについて (その多くはまったく同じ不正な文字をチェックする必要があるだけです)、新しい仮想属性を使用しなければならないことです。基本的に同じコードを繰り返すだけです:

def flexible_taxes
  taxes
end

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

強力なパラメーターを設定しながら、多くの異なるフィールドに共通の共有属性を設定する方法はありますか?

4

2 に答える 2

0

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

于 2014-02-17T05:37:33.573 に答える
0

いつでもメタ プログラミングを使用して、この繰り返されるコードをすべて動的に生成できます。

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

今はこのコードをテストしていませんが、最小限の反復で探していることを実行するはずです。また、柔軟なメソッド作成ロジックをモデル自体の外に分離します。必要に応じて、このモジュールを他のクラスで再利用することもできます。

于 2014-02-17T05:38:12.807 に答える