2012-01-26 15 views
4

ようにhas_manyのリストを処理すると、この単純な考えてみましょう私は「りんご」配列の一時コピーを作成したいここで今のActiveRecord:has_manyの関係:単純な配列

class Basket < ActiveRecord::Base 
    has_many :apples 
    ... 
end 

class Apple < ActiveRecord::Base 
    belongs_to :basket 
end 

を、私はバスケットクラスのメソッドを持っています一時コピーを操作します。手始めに、私は次のように一時的なコピーに新しい要素を追加したい:

class Basket < ActiveRecord::Base 
    has_many :apples 

    def do_something 
     #create a temporary working copy of the apples array 
     temp_array = self.apples 

     #create a new Apple object to insert in the temporary array 
     temp_apple = Apple.new 

     #add to my temporary array only 
     temp_array << temp_apple 

     #Problem! temp_apple.validate gets called but I don't want it to. 
    end 
end 

私はこれを行うと、私は私にそれを追加しようとすると、検証ルーチンは、一時的なアップルのオブジェクトに呼び出されることがわかります一時配列。私は一時的な配列を作成した理由は、全体の理由は...

が言ったこと、私はへのブルートフォースの道を見つけたなどなど検証、データベースの挿入、など主要な配列が付属しています行動のすべてを回避することです以下に示すように、forループの中で一度にtemp_arrayオブジェクトを作成するこの問題を避けてください。これは動作しますが、それは醜いです。私はこれを達成するよりエレガントな方法があるのだろうかと思います。

class Basket < ActiveRecord::Base 
    has_many :apples 

    def do_something 
     #create a temporary working copy of the apples array 
     temp_array = [] 
     for x in self.apples 
      temp_array << x 
     end 

     #create a new Apple object to insert in the temporary array 
     temp_apple = Apple.new 

     #add to my temporary array only 
     temp_array << temp_apple 

     #Yippee! the temp_apple.validate routine doesn't get called this time!. 
    end 
end 

誰かが私が聞いたことよりもこの問題に対するより良い解決策を持っているなら、それを聞いて欲しいです。

ありがとうございます!

答えて

9

問題は、self.applesは実際には配列ではなく、それが配列/列挙型メソッドを適用すると解決される、関係です。したがって、この後に:temp_array = self.applesでも、SQLクエリが起動されていません。

シンプルなソリューションデータを取得し、強制、およびすべてのその関係の挙動を取り除くためには、単にメソッドallを使用することです:

#create a temporary working copy of the apples array 
temp_array = self.apples.all 
+0

。本当にありがとう! – Denis

2
temp_array = self.apples # => This results in an instance of ActiveRecord::Relation, not an Array 

あなたが関係に

temp_array = self.apples.all # => This will give you an Array 
を評価する明示的に試してみてください
1

self.apples.to_a(= to_array)を使用する方がより論理的です。

基本的には、ActiveRecord::Relationは、それがすべてArrayスキルが、より多くを持っている意味、Array自体を拡張するオブジェクトです。

あなたは、ActiveRecord::Relationのスキルを減らす配列に変換する必要があり、あなたが良いなら。それをしなかった

+0

まさに私が必要なもの、感謝! –

関連する問題