1

私は2つのモデルを持っています、

風景:

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 でランドスケープ レコードを更新/作成しています。新しいランドスケープ レコードと新しい関連付けられたイメージ レコードを作成する POST 要求の例を次に示します。

{
  "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"
  }

}

サーバーがこれを受信すると、吐き出します

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

これはある種の循環参照の問題のようですが、それを修正する方法は明確ではありません。また興味深いのは、autosave_associated_records_for_images が呼び出されていないように見えることです (また、その関数のドキュメントはほとんどなく、Rails のソースを調べる必要がありました)。

私は、accepts_nested_attributes_for に関するほぼすべての SO 投稿を読んだことがありますが、運がありません。

アップデート

現在レコードを作成していますが、Rails から画像データを Image モデルに渡すことができません。説明しましょう:

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_associated_records_for_images を定義していないときに起こることです。ただし、次のように定義すると:

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

次の出力が表示されます。

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)

これは非常に奇妙です!リレーションシップは適切に作成されていますが、実際には、送信するデータをデータベースに入力していません。何か案は?

4

3 に答える 3

2

ここでのソリューションのいずれも機能しませんでした。代わりに、パラメーターをループしてコントローラーで手動でこれを行いました。

于 2012-06-25T00:01:31.910 に答える
0

エラーの原因は次のとおりだと思います。

Image.find(image.id)

実際、何も見つからない場合、これは例外を吐き出します。

単純に replace_it を次のように置き換えます。

Image.find_by_id(image.id)

nil何も見つからない場合は吐き出します。

于 2011-07-21T20:19:14.617 に答える
0

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

于 2011-07-23T02:26:11.307 に答える