2012-04-01 11 views
1

ネストされた属性を取得するのは難しいです。 Railscast 196の作業から、私は基本的なネスティングを行う自分のアプリケーションをセットアップしようとしました。ユーザーはスカベンジャー狩りを作成できます。各狩りは、一連の作業で構成されています(いずれかの狩猟に属することができます)。私は少し助けを受けたheresimilar issueとの投稿から学ぶことを試みたが、私はまだ固執している。私は何時間もハッキングしていて、レンガの壁にぶつかった。このコードではRails:モデルはネストされた属性を受け入れますが、コントローラは気にしないようです。

class HuntsController < ApplicationController 

    def index 
    @title = "All Hunts" 
    @hunts = Hunt.paginate(:page => params[:page]) 
    end 

    def show 
    @hunt = Hunt.find(params[:id]) 
    @title = @hunt.name 
    @tasks = @hunst.tasks.paginate(:page => params[:page]) 
    end 

    def new 
    if current_user?(nil) then  
     redirect_to signin_path 
    else 
     @hunt = Hunt.new 
     @title = "New Hunt" 
     3.times do 
     #hunt = @hunt.tasks.build 
     #hunt = @hunt.hunt_tasks.build 
     hunt = @hunt.hunt_tasks.build.build_task 
     end 
    end 
    end 

    def create 
    @hunt = Hunt.new(params[:hunt]) 
    if @hunt.save 
     flash[:success] = "Hunt created!" 
     redirect_to hunts_path 
    else 
     @title = "New Hunt" 
     render 'new'  
    end 
    end 
.... 
end 

、私は試してみて、新しい狩りを作成するとき、私は(それは未定義です)何のメソッド「build_task」がないことを聞いています。だから私はその行を削除し、上記のコメントのコードの2番目のビットを使用すると、私は以下のエラーが表示されます。

NoMethodError in Hunts#new 

    Showing /Users/bendowney/Sites/MyChi/app/views/shared/_error_messages.html.erb where line #1 raised: 

    You have a nil object when you didn't expect it! 
    You might have expected an instance of ActiveRecord::Base. 
    The error occurred while evaluating nil.errors 
    Extracted source (around line #1): 

    1: <% if object.errors.any? %> 
    2: <div id="error_explanation"> 
    3:  <h2><%= pluralize(object.errors.count, "error") %> 
    4:   prohibited this <%= object.class.to_s.underscore.humanize.downcase %> 

    Trace of template inclusion: app/views/tasks/_fields.html.erb, app/views/hunts/_fields.html.erb, app/views/hunts/new.html.erb 

そして、私はハントコントローラにコメントアウトのコードの最初のビットを使用するとき、私は私の「新しい」方法は、いないに関わらず一定であることを私に告げるエラーが表示されます。

NameError in HuntsController#new 
uninitialized constant Hunt::Tasks 

Iを私のウィットの終わりで。正確に何が間違っているのかに関する提案はありますか?それともここでの戦略は、私のモデルです:

class Hunt < ActiveRecord::Base 
     has_many :hunt_tasks 
     has_many :tasks, :through => :hunt_tasks #, :foreign_key => :hunt_id 

     attr_accessible :name 
     validates :name, :presence => true, 
         :length => { :maximum => 50 } , 
         :uniqueness => { :case_sensitive => false } 
    end 

    class Task < ActiveRecord::Base 

     has_many :hunt_tasks 
     has_many :hunts, :through => :hunt_tasks#, :foreign_key => :hunt_id 

     attr_accessible :name 
     validates :name, :presence => true, 
         :length => { :maximum => 50 } , 
         :uniqueness => { :case_sensitive => false } 

    end 

    class HuntTask < ActiveRecord::Base 
     belongs_to :hunts # the id for the association is in this table 
     belongs_to :tasks 
    end 
+1

ネストされた属性は、道路を噛み砕く方法を持っています。その道を進む前にフォームクラスを使用するオプションを探します(http://blog.codeclimate.com/blog/2012/10/17のポイント3を参照)。/7-ways-to-decompose-fat-activerecord-models /これに可能なアプローチの1つ) – bbozo

答えて

1

モデルの2つの間に関連付けを作成するときは、関係の定義方法に応じてモデルに機能を追加します。それぞれの種類は、モデルに異なる機能を追加します。

私は本当にこのガイドを読んでお勧めします - >ここでhttp://guides.rubyonrails.org/association_basics.html

あなたは協会の各異なるタイプによって追加されますどの機能を見ることができます。私は小さなサンプルプログラムのような...

class HuntsController < ApplicationController 
    # GET /hunts 
    # GET /hunts.json 
    def index 
    @hunts = Hunt.all 

    respond_to do |format| 
     format.html # index.html.erb 
     format.json { render json: @hunts } 
    end 
    end 

    # GET /hunts/1 
    # GET /hunts/1.json 
    def show 
    @hunt = Hunt.find(params[:id]) 

    respond_to do |format| 
     format.html # show.html.erb 
     format.json { render json: @hunt } 
    end 
    end 

    # GET /hunts/new 
    # GET /hunts/new.json 
    def new 
    @hunt = Hunt.new 
    3.times do |i| 
     t = @hunt.hunt_tasks.build 
     t.name = "task-#{i}" 
    end 

    respond_to do |format| 
     format.html # new.html.erb 
     format.json { render json: @hunt } 
    end 
    end 

    # GET /hunts/1/edit 
    def edit 
    @hunt = Hunt.find(params[:id]) 
    end 

    # POST /hunts 
    # POST /hunts.json 
    def create 
    @hunt = Hunt.new(params[:hunt]) 

    respond_to do |format| 
     if @hunt.save 
     format.html { redirect_to @hunt, notice: 'Hunt was successfully created.' } 
     format.json { render json: @hunt, status: :created, location: @hunt } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @hunt.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PUT /hunts/1 
    # PUT /hunts/1.json 
    def update 
    @hunt = Hunt.find(params[:id]) 

    respond_to do |format| 
     if @hunt.update_attributes(params[:hunt]) 
     format.html { redirect_to @hunt, notice: 'Hunt was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: "edit" } 
     format.json { render json: @hunt.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /hunts/1 
    # DELETE /hunts/1.json 
    def destroy 
    @hunt = Hunt.find(params[:id]) 
    @hunt.destroy 

    respond_to do |format| 
     format.html { redirect_to hunts_url } 
     format.json { head :no_content } 
    end 
    end 
end 

し、このモデル-関係

class Hunt < ActiveRecord::Base 
    has_many :hunt_tasks 
end 

class HuntTask < ActiveRecord::Base 
    belongs_to :hunt 
end 

を行うと、ビューのどこかにこのスニペットを追加した場合 http://guides.rubyonrails.org/association_basics.html#detailed-association-reference

// _form.html

狩り
<% @hunt.hunt_tasks.each do |t| %> 
    <li><%= t.name %></li> 
<% end %> 

3つのタスクが作成されたことを確認して、定期的な出力を得ています。

+0

おい、あなたは素晴らしいです。ありがとうございました! –

+0

私はあなたを助けることができてうれしい=) – mober

1

あなたはHuntsController新しいアクションで hunttask = @hunt.build_hunt_task を試してみましたか?

http://guides.rubyonrails.org/association_basics.html#detailed-association-reference

+0

私はそれを試してみましたが、別の方法エラーもありません。 'NoMethodError in HuntsController#new []:ActiveRecord :: Relation'のための未定義メソッド' build_hunt_task ' –

+0

私は申し訳ありません、has_one関係に付属しているビルダーメソッドを提案しました...ここでは、has_manyそれに応じてdocs - > http://guides.rubyonrails.org/association_basics.html#has_many-association-reference は '@ hunt.hunt_tasks.build'メソッドを提供します。すでに使用しようとしましたが、コメントアウトしました。あなたの理由は何でしたか? – mober

+0

'@ hunt.hunt_tasks.build'をコメントアウトする私の理由は、最後のコメントにあなたが言及したエラーメッセージを返すということでした。私は最後のコメントであなたが何を意味しているか正確にはわかりません。あなたは明確にしますか? –

0

あなたが見ているの即時エラーがアプリ/ビュー/共有/ _error_messages.html.erbです。オブジェクトが定義されていない場合、おそらくその部分が呼び出された場所を見つける必要があります。検索:アプリ/ビュー/作業中で発見した場合、あなたは、どこかのアプリ/ビュー/狩りでそれを見つけた場合は

render :partial=>"/shared/error" 

render :partial=>"/shared/error", :locals=>{:object=>@hunt} 

と交換し、@task

で@huntを置き換えます

これは、少なくとも実際のエラーの内容を表示します。

+0

ハントビューのnew.html.erbをこの '<%= render 'shared/error_messages'、:locals => {:object => @ hunt}%>'に変更すると、前と同じエラーです。 –

関連する問題