2011-07-21 27 views
1

、私は2つのモデルを持っているaccepts_nested_attributes_for

風景を置く/ポストにネストされたレコードを作成します。

class Landscape < ActiveRecord::Base 
    has_many :images, :as => :imageable 
    accepts_nested_attributes_for :images, :allow_destroy => true 
    attr_accessible :id, :name, :city, :state, :zip, :gps, :images, :images_attributes, :address1 

    def autosave_associated_records_for_images 
    logger.info "in autosave" 
    images.each do |image| 
     if new_image = Image.find(image.id) then 
     new_image.save! 
     else 
     self.images.build(image) 
     end 
    end 
    end 
end 

画像:

class Image < ActiveRecord::Base 
    belongs_to :imageable, :polymorphic => true 
end 

私はポストを送信し、iPhoneからの要求を入れていますjsonでランドスケープレコードを更新/作成する。ここで

{ 
    "landscape":{ 
    "id":0, 
    "name":"New Landscape", 
    "city":"The City", 
    "state":"LA", 
    "zip":"71457", 
    "images_attributes":[ 
     { 
     "id":0, 
     "image_data":"image data image data image data", 
     "is_thumbnail":1 
     } 
    ], 
    "address1":"1800 Fancy Road" 
    } 

}

新しい風景レコードを作成するには、例えば、POSTリクエストと新しい関連する画像記録は、サーバーがこれを受信した場合、それは

ActiveRecord::RecordNotFound (Couldn't find Image with ID=0 for Landscape with ID=0): 

を出してくれるので、これがあると思われます何らかの循環参照の問題がありますが、それを修正する方法については明確ではありません。また興味があるのは、autosave_associated_records_for_imagesが呼び出されたように見えないことです(また、その関数のドキュメントがほとんどないので、私はソースを参照しなければなりません)。

私は運がないaccepts_nested_attributes_forのすべてのSO投稿を読んでいます。

更新

私は今作成したレコードを持っているが、私はレールがバック画像のモデルに画像データを渡すために取得することはできません。私が説明しましょう:

Started POST "/landscapes" for 127.0.0.1 at 2011-07-22 19:43:23 -0500 
    Processing by LandscapesController#create as JSON 
    Parameters: {"landscape"=>{"name"=>"asdf", "id"=>0, "address1"=>"asdf", "city"=>"asdf", "images_attributes"=>[{"id"=>0, "image_data"=>"Im a bunch of image data image data image data", "is_thumbnail"=>1}]}} 
    SQL (0.1ms) BEGIN 
    SQL (1.6ms) describe `landscapes` 
    AREL (0.2ms) INSERT INTO `landscapes` (`address1`, `city`, `gps`, `name`, `state`, `zip`, `updated_at`, `created_at`) VALUES (NULL, NULL, NULL, NULL, NULL, NULL, '2011-07-23 00:43:23', '2011-07-23 00:43:23') 
    SQL (1.0ms) describe `images` 
    AREL (0.1ms) INSERT INTO `images` (`image_caption`, `image_data`, `is_thumbnail`, `created_at`, `updated_at`, `imageable_id`, `imageable_type`) VALUES (NULL, NULL, NULL, '2011-07-23 00:43:23', '2011-07-23 00:43:23', 46, 'Landscape') 
    SQL (0.2ms) COMMIT 
Completed 201 Created in 37ms (Views: 2.2ms | ActiveRecord: 14.5ms) 

私はautosave_asociated_records_for_imagesを定義していませんときに何が起こるかだこと。しかし、私はそうのようにそれを定義します。

Started POST "/landscapes" for 127.0.0.1 at 2011-07-22 19:50:57 -0500 
    Processing by LandscapesController#create as JSON 
    Parameters: {"landscape"=>{"name"=>"asdf", "id"=>0, "address1"=>"asdf", "city"=>"asdf", "images_attributes"=>[{"id"=>0, "image_data"=>"Im a bunch of image data image data image data", "is_thumbnail"=>1}]}} 
    SQL (0.1ms) BEGIN 
    SQL (1.6ms) describe `landscapes` 
    AREL (0.2ms) INSERT INTO `landscapes` (`address1`, `city`, `gps`, `name`, `state`, `zip`, `updated_at`, `created_at`) VALUES (NULL, NULL, NULL, NULL, NULL, NULL, '2011-07-23 00:50:57', '2011-07-23 00:50:57') 
in autosave 
[#<Image id: nil, image_caption: nil, image_data: nil, is_thumbnail: nil, created_at: nil, updated_at: nil, imageable_id: nil, imageable_type: "Landscape">] 
    SQL (0.2ms) COMMIT 
Completed 201 Created in 32ms (Views: 2.2ms | ActiveRecord: 2.1ms) 

これは非常に奇妙です:私は次の出力を参照してください

def autosave_associated_records_for_images 
    logger.info "in autosave" 
    logger.info images.to_s 
end 

を!それは関係を適切に作成していますが、実際には私が送信しているデータをデータベースに取り込むわけではありません。何か案は?

+0

POSTでparamsに** id **を送信する理由は何ですか? – Anatoly

+0

コントローラコードをコピーして貼り付けできますか? – Anatoly

+0

より良いことがあります – rubish

答えて

2

私は決してここで解決策のいずれかを得たことはありません。私が代わりにしたのは、コントローラで手作業で行いました。

+0

同様の問題がありますが、ActiveRecordはこれを理解するのに十分なほどスマートでなければなりません。メチンクス。 – wulftone

+0

私も同様の問題があります。私はいくつかのRailsのバグがあると思っています。 – GreenEggs

0

私はエラーがから来ていると思います:

Image.find(image.id) 

何も見つからなかったとき、確かに、これは例外を吐きます。

は単純でreplace_it:

Image.find_by_id(image.id) 

何も見つからなかった場合にはnilを吐くだろう。

+0

私はそれが働いた機会にこれを試しましたが、それはしませんでした。投稿したコードを見ると、autosave_associated_records_for_imagesメソッド内からのロギングを試みたことがわかります。何も記録されていないので、関数が呼び出されていないように見えます。 –

+0

しかし、 'autosave_associated_records_for_images'は' after_create'または 'after_update'として呼び出されます。あなた自身の' before_save'を作成してみませんか? – apneadiving

+0

私はbefore_saveで試しました。それはうまくいかず、ログには何も書き込まれませんでした。 autosave_associated_records_for_imagesはafter_createとしてコールされています。私はそれに関する多くの文書を見つけることができません。 –

0

autosave_associated_records_for_imagesメソッドには、そのクラスに対する責任が多すぎます。解決方法は、このメソッドロジックをImageクラスに移動することです。すべてのActiveRecordクラスインスタンスには、before_validation、before_createなどのデフォルトのコールバックがあります。私はあなたが最初にそれらを使用することをお勧めします

関連する問題