2013-10-07 6 views
6

までのレールフォームでネストされた関連付けを作成しようとしましたが、私はこれに関する以前の質問を投稿し、多くの関連情報を読むことをお勧めしました。私はそれを読んで約30種類のソリューションを実装しようとしました。どれも私のために働いていません。has_manyから

ここに私が持っているものがあります。

私はMiniaturesモデルを持っています。 私はManufacturersモデルを持っています。 ミニチュアには、プロダクションモデルを通じて多くのメーカーがあります。

アソシエーションは、自分のビューに表示してコンソールで作成できるので、正しく設定されているようです。私が問題を抱えているところは、Miniatures NEWとEDITビューを作成してProductionsテーブルに更新させることです。

コンソールでは、コマンド@miniature.productions.create(manufacturer_id: 1)が機能します。これは、私がフォームで同じことをすることができるはずだと信じさせます。

私は自分の問題は常にMiniaturesコントローラ、特にCREATE機能にあると考えています。私はそこに他の多くの人々のソリューションを試してみましたが、誰もそのトリックをやっていません。私のfield_for私のフォームのものが間違っている可能性がありますが、それはあまり目立たないようです。

私は数日間このことに悩まされていました。私が取り組むことができる他のことがありますが、この関連が不可能な場合は、アプリケーション全体を再考する必要があります。

フォームではプロダクションテーブルに行が作成されますが、すべての重要なmanufacturer_idは含まれません。

非常に助かりました。

私の新しい小型フォーム

<% provide(:title, 'Add miniature') %> 
<h1>Add a miniature</h1> 

<div class="row"> 
    <div class="span6 offset3"> 
    <%= form_for(@miniature) do |f| %> 
     <%= render 'shared/error_messages', object: f.object %> 
     <%= f.label :name %> 
     <%= f.text_field :name %> 
     <%= f.fields_for :production do |production_fields| %> 
     <%= production_fields.label :manufacturer_id, "Manufacturer" %> 
     <%= production_fields.select :manufacturer_id, options_from_collection_for_select(Manufacturer.all, :id, :name) %> 
     <% end %> 
     <%= f.label :release_date %> 
     <%= f.date_select :release_date, :start_year => Date.current.year, :end_year => 1970, :include_blank => true %> 

     <%= f.submit "Add miniature", class: "btn btn-large btn-primary" %> 
    <% end %> 
    </div> 
</div> 

ミニチュアコントローラ

class MiniaturesController < ApplicationController 
    before_action :signed_in_user, only: [:new, :create, :edit, :update] 
    before_action :admin_user,  only: :destroy 

    def productions 
    @production = @miniature.productions 
    end 

    def show 
    @miniature = Miniature.find(params[:id]) 
    end 

    def new 
    @miniature = Miniature.new 
    end 

    def edit 
    @miniature = Miniature.find(params[:id]) 
    end 

    def update 
    @miniature = Miniature.find(params[:id]) 
    if @miniature.update_attributes(miniature_params) 
     flash[:success] = "Miniature updated" 
     redirect_to @miniature 
    else 
     render 'edit' 
    end 
    end 
    def index 
    @miniatures = Miniature.paginate(page: params[:page]) 
    end 

    def create 
    @miniature = Miniature.new(miniature_params) 
    if @miniature.save 
     @production = @miniature.productions.create 
     redirect_to @miniature 
    else 
     render 'new' 
    end 
    end 

    def destroy 
    Miniature.find(params[:id]).destroy 
    flash[:success] = "Miniature destroyed." 
    redirect_to miniatures_url 
    end 

private 
    def miniature_params 
     params.require(:miniature).permit(:name, :release_date, :material, :scale, :production, :production_attributes) 
    end 

    def admin_user 
     redirect_to(root_url) unless current_user.admin? 
    end 

    def signed_in_user 
     unless signed_in? 
     store_location 
     redirect_to signin_url, notice: "Please sign in." 
     end 
    end 
end 

ミニチュアモデル

class Miniature < ActiveRecord::Base 
    has_many :productions, dependent: :destroy 
    has_many :manufacturers, :through => :productions 
    accepts_nested_attributes_for :productions 

    validates :name, presence: true, length: { maximum: 50 } 
    validates :material, presence: true 
    validates :scale, presence: true 
    validates_date :release_date, :allow_blank => true 

    def name=(s) 
    super s.titleize 
    end 

end 

生産モデル

class Production < ActiveRecord::Base 
    belongs_to :miniature 
    belongs_to :manufacturer 



end 

メーカーモデル

class Manufacturer < ActiveRecord::Base 
    has_many :productions 
    has_many :miniatures, :through => :productions 
    validates :name, presence: true, length: { maximum: 50 } 
    accepts_nested_attributes_for :productions 
end 
+1

が広く、このを通じて見ていないが、あなたは関係が上構築され、あなたの作成したアクションに問題があります'@ miniature'の代わりに' @ Miniature'(大文字の 'm')を使用しています(小文字の 'm'はインスタンス変数@miniatureと一致します)。 –

+0

ああ、ありがとうございます。私はそれを修正し、 "親が保存されるまで作成できません"という行に沿ってエラーを投げたので、 "if @ miniature.save"行の下に行を移動しました。これで、Productionsテーブルに行が作成されますが、manufacturer_idフィールドには入力されません。私は残念ながらここに来ました。 – Ossie

答えて

8

の代わりに呼び出す:

def new 
    @miniature = Miniature.new(miniature_params) 
    @miniature.productions.build 
end 

def create 
    @miniature = Miniature.new(miniature_params) 
    if @miniature.save 
    redirect_to @miniature 
    else 
    render 'new' 
    end 
end 

@production = @miniature.productions.create 

はRailsの "ビルド" の方法を試してみてください

ビルドメソッドを使用すると、ActiveRecordのオートセーブアソシエーション機能が使用されます。

例えば、あなたはまた、あなたのparamsメソッドを更新する必要がhttp://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html

を参照してください。また

def miniature_params 
    params.require(:miniature).permit(:name, :release_date, :material, :scale, productions_attributes: [:manufacturer_id]) 
end 

あなたfields_forは(私が思う)複数でなければなりません...

<%= f.fields_for :productions do |production_fields| %> 
+0

これは、 "if @miniature save"行の上に行をシフトすることができますが、まったく同じように動作します。テーブルに新しい行が表示されますが、manufacturer_idは含まれていません。別の方法でフォームを作成する必要があるか、コントローラーにその特定のパラメーターを使用させる必要があるかのいずれかでなければなりません。 Oof。 – Ossie

+0

私はparamsビットでさまざまな組み合わせを試みました。これは素晴らしそうだが、manufacturer_idはまだプロダクションに渡されません。それは非常に正しいでしょうか? – Ossie

+1

パラメータを渡してもフィルタリングされているかどうかをログから確認できますか?それとも全くそれを通さないのでしょうか?申し訳ありませんが、私は多すぎる助けをしていない、私はフォームオブジェクトを使用するために、ネストされたフォームを使用しないようにしてください...#3フォームオブジェクト、ここでチェックアウト:http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activeレコードモデル/ –