1

3つの異なる属性で同じタスクを実行する必要があるメソッドをドライアップしようとしています。このような:

if !@item.picture.blank?
  picture_copy = Picture.new
  picture_copy.save!
  item_copy.picture = picture_copy
end

if !@item.picture_for_x.blank?
  picture_for_x_copy = PictureForX.new
  picture_for_x_copy.save!
  item_copy.picture_for_x = picture_for_x_copy
end

if !@item.picture_for_y.blank?
  picture_for_y_copy = PictureForY.new
  picture_for_y_copy.save!
  item_copy.picture_for_y = picture_for_y_copy
end

つまり、基本的に同じコードを実行していますが、異なるオブジェクトをインスタンス化してから、それらを異なる属性に割り当てています。リフレクションを使ってこのビューを乾かす方法があるはずだと感じています。これらの属性とオブジェクトをヘルパーメソッドに渡される文字列として参照できる方法はありますか?

さまざまな理由から、.cloneまたは.dupを使用することはできません。主な理由は、バイナリファイルポインタが関係していて、ディープコピーも必要だからです。

4

2 に答える 2

2
{
  picture:       Picture,
  picture_for_x: PictureForX,
  picture_for_y: PictureForY
}.each do |name,klass|
  if !@item.send(name).blank?
    copy = klass.new
    copy.save!
    item_copy.send("#{name}=",copy)
  end
end

Rubyに、外部で使用できるプロパティや属性はなく、メソッドだけであることに注意してください(プロパティにアクセスしているように見えるように、かっこなしで呼び出すこともできます。インスタンス変数の値を返すだけの場合もあります)。 。

Object#sendは、変数に格納されている名前に基づいてメソッドを呼び出すことができる魔法のメソッドです。

于 2012-05-25T17:05:15.630 に答える
1
def picture_for_x_blank?(s = "")
  s = "_for_#{s}" unless s.empty?
  m = "picture#{s}"

  unless @item.send(m).blank?
    copy = Kernel::const_get(m.camelize).new
    copy.save!
    item_copy.send("#{m}=", copy)
  end
end

picture_for_x_blank?
picture_for_x_blank?("x")
picture_for_x_blank?("y")
于 2012-05-25T17:13:41.037 に答える