1
class A
  attr_accessor :dab
  ....
end

これで、Aのインスタンスの配列ができました。

arr = [A.new, A.new, A.new]

Aそして今、配列に存在するクラスのすべてのインスタンスに値を設定したいと思いますarr。これを行うためのショートカットはruby/railsにありますか?

また、私はAから継承していますActiveRecord::Base

そして、私の実際の必要性は次のとおりです。

A.find_all_by_some_condition.all.dabs = 2

したがって、見つかったすべてのオブジェクトはdab2に設定されます。

これに対するショートカットはありますか?

4

2 に答える 2

1

配列からクラスAのアイテムを取得するには、select/find_allを使用できます。

arr.select { |el| el.class == A }またarr.select { |el| A === el }

対応するクラスではなく、複数のオブジェクトに値を割り当てようとしているにもかかわらず、実際の結果を達成するため。クラスAは実際のオブジェクトを定義するのではなく、オブジェクトが作成されるときに使用する青写真を定義するだけです。したがって、Aのすべてのインスタンスの値を割り当てる方法を見つけることは、あなたが求めているものではありません(ただし、あなたが求めていたもののポイントを見逃した可能性があります)

オブジェクトの配列に値を割り当てるには、これが機能します。

A.find_all_by_some_condition.each { |a| a.dab = 2 }

おそらく、後でそれらを保存したいので、今arr.each(&:save)は便利かもしれません。まだわからない場合は、アンパサンドを調べてください。非常に便利。

于 2012-06-16T10:43:53.813 に答える
0

デフォルトではこれを直接行うことはできませんが、Rubyを使用してそのようなものを構築することはできますmethod_missing

2つの解決策:

解決策1-ラッパークラスを使用する

このクラスMArrayをmulti-assign-arrayと呼びます。

class MArray
  def initialize(inner_array)
    @inner = inner_array
  end

  def method_missing(meth, value)
    # Check if assignement, and if it is then run mass-assign
    if meth.to_s =~ /^\w+=$/
      @inner.each { |itm| itm.send(meth, value) }
    else
      raise ArgumentError, "MArray: not an assignment"
    end
  end
end

また、ラッピングが行われるようMArrayに、のサポートを追加する必要があります。「一括割当」Arrayのメソッドを呼び出します。mas

class Array
  def mas
    # Wrap MArray around self
    MArray.new(self)
  end
end

使い方は簡単です:

Blob = Struct.new(:dab)
arr = [Blob.new] * 3
arr.mas.dab = 123
arr
=> [#<struct Blob dab=123>, #<struct Blob dab=123>, #<struct Blob dab=123>]

解決策2-大量割り当てサポートを直接作成するArray

で直接変更するため、これはもう少し「危険」method_missingですArray。奇妙な副作用が発生する可能性があります(たとえばmethod_missing、他のライブラリによってすでに再定義されている場合や、意図しないときに誤って一括割り当てを呼び出した場合など)。

これは、複数の単語(で終わる単語s)を含む割り当てを検出しようとし、その後、一括割り当てをトリガーすることで機能します。

class Array
  def method_missing(meth, *args, &block)
    # Check for plural assignment, and as an added safety check also
    # see if all elements in the array support the assignment:
    if meth.to_s =~ /^(\w+)s=$/ && 
       self.all? { |itm| itm.respond_to?("#{$1}=") }
      self.each { |itm| itm.send("#{$1}=", *args) }
    else
      super
    end
  end
end

使用量は、次の場合よりもさらに短くなりMArrayます。

Blob = Struct.new(:dab)
arr = [Blob.new] * 3
arr.dabs = 123
arr
=> [#<struct Blob dab=123>, #<struct Blob dab=123>, #<struct Blob dab=123>]
于 2012-06-16T13:38:09.653 に答える