2012-01-05 18 views
0

任意のより多くの間違った答えを防止するためのアップデート:豊富な多対多の関連付けのフォームをネストする方法は?

  • 製品は
  • 多くの製品イメージを持っている多くの製品と多くのシーン
  • 製品がありますが、製品を作るために、各シーンのために一つの画像を持っています画像そのシーンに合わせ

オリジナルの質問:

私は、3番目のテーブル(ProductImages)を通して豊富な多対多の関係を持つ2つのテーブル(シーンと製品)を持っています。 ProductImagesには、scene_id、product_id、およびimageの3つのフィールドがあります。今度は、各シーンエンティティのProductフォーム内にProductImageのインスタンスのフォームをネストしたいと思います。

私は3つのシーンがあるとき、それぞれの製品フォームに3つの「イメージ」フィールドを表示したいと考えています。リレーションがまだ存在しない場合でも、3つのフィールドは常に表示されます。

誰かがこれを行う方法を教えてもらえますか?私は正しい関係を定義している(私は思う)、私は画像の添付ファイルのためのPaperclipプラグインを使用している。


更新

私のモデルは、ここでの考え方ですが、どのように見えるかを明確にする:

Scenes: 
| id | name  | background-image | 
|----|-----------|--------------------| 
| 1 | kitchen x | a picture   | 
| 2 | kitchen y | an other picture | 
| 3 | kitchen z | just other picture | 

Products: 
| id | name   | price | material | 
|----|--------------|-------|----------| 
| 1 | countertop x | 100 | wood  | 
| 2 | countertop y | 33 | metal | 
| 3 | tap x  | 95 | chrome | 

ProductImages: 
| id | product | scene | image  | 
|----|---------|-------|-----------| 
| 1 | 1  | 1  | some pic | 
| 2 | 1  | 2  | good pic | 
| 3 | 1  | 3  | weird pic | 
| 4 | 2  | 1  | a pic  | 
| 5 | 2  | 2  | one pic | 
| 6 | 2  | 3  | other pic | 

は、そして、私の目標は巣に製品の形の内部ProductImagesの画像フィールドのためのフォームです。

このメソッドをproducts_controller.rbに追加しました。 "ep"編集しようとしている製品ですか?このメソッドは、編集メソッドの最初に呼び出されます。

def check_relation_with_scenes(ep) 
    Scene.all.each do |s| 
     ProductImage.find_or_create_by_product_id_and_scene_id(:product_id => ep.id, :scene_id => s.id) 
    end 
end 
+0

「シーン」は実際に何かもっと説明してください。商品が掲載されている設定(写真)ですか?そして、 'ProductImages'テーブルの余分なイメージがクローズアップされますか?または、使用例のいくつかの種類ですか?私が正しく理解していれば、シーンごとに写真をアップロードすることができます:正しい? – nathanvda

+0

シーンは実際に複数の製品が同時に表示される写真です。余分な画像はクローズアップではありません。各シーンには、角度が異なる可能性のある異なる写真と、稲妻があります。したがって、各シーンで同じ製品を正しく表示するには、実際に各シーンの各製品の写真があります。 –

+0

3つの関連モデルのルビコードとそれらの関係も表示してください。 – dombesz

答えて

1

をapplication.js、これらの関連は非常に奇妙な感じ、希望私のデザインを個人的に再考する。私はあなたの質問に多くの回答がなかった理由はこれを推測しています。

モデル/ scene.rb

class Scene < ActiveRecord::Base 
    has_many :product_images 
    has_many :products, :through=>:product_images 
    accepts_nested_attributes_for :products 
end 

モデル/ product.rb

class Product < ActiveRecord::Base 
    has_many :product_images 
    has_many :scenes, :through=>:product_images 
    accepts_nested_attributes_for :product_images 
end 

モデル/ product_image.rb:かかわらず、私は、これはあなたが探しているものの要旨以上だと思います

class ProductImage < ActiveRecord::Base 
    belongs_to :scene 
    belongs_to :product 
end 

私はシーンがあなたの「親」の形で、製品が各シーンにネストされていることを想定している - と各製品product_image形式を持ちます。

ビュー/シーン/ _form.html.erb

<%= form_for @scene do |f| %> 
    <%= f.error_messages %> 
    <p> 
    <%= f.label :name %><br /> 
    <%= f.text_field :name %> 
    </p> 
    <p> 
    <%= f.label :background_image %><br /> 
    <%= f.text_field :background_image %> 
    </p> 
    <fieldset><legend>Products</legend> 
    <%= f.fields_for :products do |product_form| %> 
    <%= render :partial=>"/products/form", :locals => { :f => product_form } %> 
    <% end %> 
    </fieldset> 

    <p><%= f.submit %></p> 
<% end %> 

ビュー/製品/ _form.html.erb

<p> 
    <%= f.label :name %><br /> 
    <%= f.text_field :name %> 
    </p> 
    <p> 
    <%= f.label :price %><br /> 
    <%= f.text_field :price %> 
    </p> 
    <p> 
    <%= f.label :material %><br /> 
    <%= f.text_field :material %> 
    </p> 

    <fieldset><legend>Product Images</legend> 
    <%= f.fields_for :product_images do |pi_form| %> 
    <%= render :partial=>"/product_images/form", :locals => { :f => pi_form } %> 
    <% end %> 
    </fieldset> 

ビュー/ product_images/_form.html.erb

<p> 
    <%= f.hidden_field :scene_id %> 
    <%= f.hidden_field :product_id %> 
</p> 

<p> 
    <%= f.label :image %><br /> 
    <%= f.text_field :image %> 
</p> 

controllers/scenes_controller.rb

def new 
@scene = Scene.new 
3.times do 
    @scene.products.build.product_images.build 
end 
end 

def create 
@scene = Scene.new(params[:scene]) 
if @scene.save 
    redirect_to @scene, :notice => "Successfully created scene." 
else 
    render :action => 'new' 
end 
end 

product_imagesテーブルに 'scene'と 'product'の列が表示されていることもあなたのテーブルでわかりました。たぶん入力ミスですが、列はそれぞれscene_idとproduct_idになるはずです。がんばろう!あなたは、次のモデル構造を持っていると仮定すると

+0

さて、製品のフォームは、あなたの答えが正しいかもしれないということから、シーンに入れ子にする必要はありません。そしてそれはタイプミスではありませんでした、私はちょうど小さなスペースを保存していたxD確かに私は_idを使用しています。 –

+0

これをより良くするための提案は歓迎です。私の専門知識では、これを現在のデザインよりも上手くやり遂げることができませんでした。 –

+0

ええと、これは私に 'ActiveRecord :: HasManyThroughAssociationPolymorphicSourceError(素晴らしいもの)を与えます、"多相オブジェクト 'Product#product' "'にhas_many:throughアソシエーション 'Scene#products'を持つことはできません。私はそれを理解しているように見えることはできません... 'accepts_nested_attributes_for:products'が削除されたらすぐになくなりました。 –

0

投稿したコードが不足しているとします。私はそれが次Railscastsにご案内するのがベストだと思う:彼らは確かにあなたの問題を解決するのに役立つとビールを割れに非常に近いあなた持参してください

http://railscasts.com/episodes/196-nested-model-form-part-1

http://railscasts.com/episodes/197-nested-model-form-part-2

http://railscasts.com/episodes/75-complex-forms-part-3

+0

railscastsは残念なことに私が記述した状況について議論していない、私はすでにそれらを見ていた。 –

1

リンクテーブルに画像情報を保持してもよろしいですか?画像はシーンに固有のもの、つまり各シーンに画像があるように見えます。

モデル/ scene.rb

class Scene < ActiveRecord::Base 

    has_many :products_scenes, :dependent => :destroy 
    has_many :products, :through => :products_scences  

    has_attached_file :scene_image, :path => "../uploads/:attachment/:id/:style/:filename", :url => "../uploads/:attachment/:id/:style/:filename" 

end 

モデル/ products_scenes。RB

class ProductsScenes < ActiveRecord::Base 

    belongs_to :product 
    belongs_to :scene 

end 

モデル/ product.rb

class Product < ActiveRecord::Base 

    has_many :products_scenes, :dependent => :destroy 
    has_many :scenes, :through => :products_scenes 

    accepts_nested_attributes_for :scenes, :allow_destroy => true 

end 

コントローラ/ product_controller.rb

class ProductsController < ApplicationController 

    def new 
    @product = Product.new 
    @product.scenes.build 
    end 
end 

ビュー/製品/ _form.hmtl.haml

= form_for(@product) do |f| 
    = render @product.scenes 
    = link_to "Add", "#add", :id => "add-scene" 

ビュー/シーン/ _scene.html.haml

= fields_for "product[scenes_attributes][]", scene do |scene_form| 
    %li.scene_list 
    .left_field 
     = scene_form.label :scene_image 
    .right_field 
     = scene_form.file_field :scene_image 
    %span.right_action_negative 
     = link_to("Remove", "#delete", :class => "delete-scene") 

公開/ JavaScriptの/私は認めなければならない

$('a#add-scene').click(function() { 
    $('#scene_list li:first').clone().find('input').val('').end().appendTo('#scene_list'); 
    }); 

    $('.delete-scene').live('click', function() { 
    if ($('#scene_list li').length > 1) 
     $(this).parent().parent().remove(); 
     else 
     alert('No scenes listed.'); 
    }); 
+0

いいえリンクテーブルを使う必要があると私は思っています。 –

+0

あなたは答えがそれではありませんでしたが、それは私が正しい方向に考えるのを助けました。ありがとう! –

0

は、ここにあなたの問題の解決策です:フォームで

class Product < ActiveRecord::Base 
    has_many :products_images 
    has_many :scenes, :through => :products_images 
    accepts_nested_attributes_for :products_images 
end 

class ProductImage < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :scene 
end 

class Scene < ActiveRecord::Base 
    has_many :products_images 
end 
あなたのコントローラで

def new 
    @product = Product.new 
    ([email protected]_images.size).times {@product.products_images.build} if @product.products_images.size < 3 
    #ensure always have at least 3 product_images initialized 
end 

<%= form_for @product do |f| %> 
    <%= f.fields_for :product_images do |pf| %> 
    <%= pf.file_field :image %> 
    <% end %> 
<% end %> 

ご不明な点がありましたら教えてください。

関連する問題