2016-03-19 10 views
0

Ich bekomme diesen Fehler undefined method 'comments' in meiner Rails-Anwendung. Ich weiß, dass ich keine verschachtelten Ressourcen der Stufe 1 machen sollte, aber ich weiß nicht, wie ich in diesem Fall den richtigen Weg finde.Rails: tief verschachtelte Ressourcen gibt Fehler: undefinierte Methode 'Kommentare'

Derzeit ist dies meine Routen:

resources :performance_indicators do 
    resources :improvement_actions do 
     member do 
     put "like" => "improvement_actions#upvote" 
     put "unlike" => "improvement_actions#downvote" 
     end 
     resources :comments 
    end 
    end 

Wie gesagt ich bekomme diese Fehlermeldung:

NoMethodError in PerformanceIndicators#show 
Showing .../app/views/comments/_form.html.erb where line #1 raised: 
undefined method `comments' for nil:NilClass 

Ich weiß nicht, ob mein Problem in der Steuerung ist. Jeder kann helfen? :)

EDIT:

Mein Beitrag/_form:

<%= form_for([@performance_indicator, @improvement_action, @improvement_action.comments.build]) do |f| %> 


    <div class="field"> 
    <%= f.label :body %><br> 
    <%= f.text_area :body %> 
    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

Das ist mein CommentsController ist:

class CommentsController < ApplicationController 
    before_action :set_comment, only: [:show, :edit, :update, :destroy] 
    before_action :authenticate_user!, except: [:index, :show] 
    before_action :set_improvement_action 


    # GET /comments 
    # GET /comments.json 
    def index 
    end 

    # GET /comments/1 
    # GET /comments/1.json 
    def show 
    end 

    # GET /comments/new 
    def new 
     @comment = @improvement_action.comments.new 
    end 

    # GET /comments/1/edit 
    def edit 
    end 

    # POST /comments 
    # POST /comments.json 
    def create 

    @comment = @improvement_action.comments.new(comment_params) 

     if @comment.save 
     format.html { redirect_to [@improvement_action.performance_indicator, @improvement_action], notice: 'Comment was successfully created.' } 
     format.json { render :show, status: :created, location: [@improvement_action, @comment] } 
     else 
     format.html { render :new } 
     format.json { render json: @comment.errors, status: :unprocessable_entity } 
    end 
    end 

    # PATCH/PUT /comments/1 
    # PATCH/PUT /comments/1.json 
    def update 
    respond_to do |format| 
     if @comment.update(comment_params) 
     format.html { redirect_to @comment, notice: 'Comment was successfully updated.' } 
     format.json { render :show, status: :ok, location: @comment } 
     else 
     format.html { render :edit } 
     format.json { render json: @comment.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /comments/1 
    # DELETE /comments/1.json 
    def destroy 
    @comment.destroy 
    respond_to do |format| 
     format.html { redirect_to comments_url, notice: 'Comment was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_comment 
     @comment = Comment.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def comment_params 
    params.require(:comment).permit(:body) 
    end 

    def set_improvement_action 
    @improvement_action = ImprovementAction.includes(:comments).find(params[:improvement_action_id]) 
    end 
end 

ist hier mein PerformanceIndicatorController:

class PerformanceIndicatorsController < ApplicationController 
    before_action :set_performance_indicator, only: [:show, :edit, :update, :destroy] 
    before_action :authenticate_user!, except: [:index, :show] 
    # GET /performance_indicators 
    # GET /performance_indicators.json 
    def index 
    @performance_indicators = PerformanceIndicator.all 
    end 

    # GET /performance_indicators/1 
    # GET /performance_indicators/1.json 
    def show 
    #@performance_indicators = PerformanceIndicator.all.order("created_at DESC") 
    end 

    # GET /performance_indicators/new 
    def new 
    @performance_indicator = PerformanceIndicator.new 
    @comments = Comment.new 
    end 

    # GET /performance_indicators/1/edit 
    def edit 
    end 

    # POST /performance_indicators 
    # POST /performance_indicators.json 
    def create 
    @performance_indicator = PerformanceIndicator.new(performance_indicator_params) 

    respond_to do |format| 
     if @performance_indicator.save 
     format.html { redirect_to @performance_indicator, notice: 'Performance indicator was successfully created.' } 
     format.json { render :show, status: :created, location: @performance_indicator } 
     else 
     format.html { render :new } 
     format.json { render json: @performance_indicator.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PATCH/PUT /performance_indicators/1 
    # PATCH/PUT /performance_indicators/1.json 
    def update 
    respond_to do |format| 
     if @performance_indicator.update(performance_indicator_params) 
     format.html { redirect_to @performance_indicator, notice: 'Performance indicator was successfully updated.' } 
     format.json { render :show, status: :ok, location: @performance_indicator } 
     else 
     format.html { render :edit } 
     format.json { render json: @performance_indicator.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /performance_indicators/1 
    # DELETE /performance_indicators/1.json 
    def destroy 
    @performance_indicator.destroy 
    respond_to do |format| 
     format.html { redirect_to performance_indicators_url, notice: 'Performance indicator was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
    end 

    def set_comment 
    @improvement_action = ImprovementAction.find(params[:improvement_action_id]) 
    @comment = Comment.find(params[:id]) 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_performance_indicator 
     @performance_indicator = PerformanceIndicator.find(params[:id]) 
    end 



    # Never trust parameters from the scary internet, only allow the white list through. 
    def performance_indicator_params 
     params.require(:performance_indicator).permit(:name, :numberTimesIdentifiedProblems, :numberTimesAnalysed) 
    end 



end 
+1

Es wird in Ihrem Kommentarformular aufgerufen. Posten Sie das. Der von Ihnen gepostete Code ist für Ihren Fehler nicht relevant. Sie rufen 'something.comments' und das' something' ist 'nil' – toddmetheny

+0

ich bearbeitet, mit dem Kommentarformular –

+0

In welcher Ansichtsseite rendern Sie diese Teildatei? – Pavan

Antwort

0

Beginnen wir mit der Fixierung der tiefen Verschachtelung.

resources :performance_indicators, shallow: true do 
    resources :improvement_actions 
end 

resources :improvement_actions, only: [] do 
    member do 
    put "like" => "improvement_actions#upvote" 
    put "unlike" => "improvement_actions#downvote" 
    end 

    resources :comments 
end 

only: [] ist ein kluger Trick, die Routen unter einer Ressource nistet aber unterdrückt die Erzeugung von Routen. Wir wollen das, da der erste Block eigentlich alle Routen erklärt, die wir brauchen.

         Prefix Verb URI Pattern                    Controller#Action 
    performance_indicator_improvement_actions GET /performance_indicators/:performance_indicator_id/improvement_actions(.:format)   improvement_actions#index 
               POST /performance_indicators/:performance_indicator_id/improvement_actions(.:format)   improvement_actions#create 
new_performance_indicator_improvement_action GET /performance_indicators/:performance_indicator_id/improvement_actions/new(.:format)  improvement_actions#new 
edit_performance_indicator_improvement_action GET /performance_indicators/:performance_indicator_id/improvement_actions/:id/edit(.:format) improvement_actions#edit 
    performance_indicator_improvement_action GET /performance_indicators/:performance_indicator_id/improvement_actions/:id(.:format)  improvement_actions#show 
               PATCH /performance_indicators/:performance_indicator_id/improvement_actions/:id(.:format)  improvement_actions#update 
               PUT /performance_indicators/:performance_indicator_id/improvement_actions/:id(.:format)  improvement_actions#update 
               DELETE /performance_indicators/:performance_indicator_id/improvement_actions/:id(.:format)  improvement_actions#destroy 
         performance_indicators GET /performance_indicators(.:format)              performance_indicators#index 
               POST /performance_indicators(.:format)              performance_indicators#create 
        new_performance_indicator GET /performance_indicators/new(.:format)             performance_indicators#new 
        edit_performance_indicator GET /performance_indicators/:id/edit(.:format)            performance_indicators#edit 
         performance_indicator GET /performance_indicators/:id(.:format)             performance_indicators#show 
               PATCH /performance_indicators/:id(.:format)             performance_indicators#update 
               PUT /performance_indicators/:id(.:format)             performance_indicators#update 
               DELETE /performance_indicators/:id(.:format)             performance_indicators#destroy 
         like_improvement_action PUT /improvement_actions/:id/like(.:format)             improvement_actions#upvote 
        unlike_improvement_action PUT /improvement_actions/:id/unlike(.:format)            improvement_actions#downvote 
        improvement_action_comments GET /improvement_actions/:improvement_action_id/comments(.:format)       comments#index 
               POST /improvement_actions/:improvement_action_id/comments(.:format)       comments#create 
       new_improvement_action_comment GET /improvement_actions/:improvement_action_id/comments/new(.:format)      comments#new 
       edit_improvement_action_comment GET /improvement_actions/:improvement_action_id/comments/:id/edit(.:format)     comments#edit 
        improvement_action_comment GET /improvement_actions/:improvement_action_id/comments/:id(.:format)      comments#show 
               PATCH /improvement_actions/:improvement_action_id/comments/:id(.:format)      comments#update 
               PUT /improvement_actions/:improvement_action_id/comments/:id(.:format)      comments#update 
               DELETE /improvement_actions/:improvement_action_id/comments/:id(.:format)      comments#destroy 

Das Unschachteln der Ressourcen bedeutet, dass es viel weniger Reifen zum Springen gibt.

class CommentsController < ApplicationController 

    before_action :set_improvement_action 

    # GET /improvement_actions/:improvement_action_id/comments/new 
    def new 
    @comment = @improvement_action.comments.new 
    end 

    # POST /improvement_actions/:improvement_action_id/comments 
    def create 
    @comment = @improvement_action.comments.new(comment_params) do |c| 
     # @todo - you should associate comment with the user who created it at some point. 
     # c.author = current_user 
    end 

    # note that you where saving the record twice! 
    if @comment.save 
     format.html { redirect_to [@improvement_action.performance_indicator, @improvement_action], notice: 'Comment was successfully created.' } 
     format.json { render :show, status: :created, location: [@improvement_action, @comment] }   
    else 
     format.html { render :new } 
     format.json { render json: @comment.errors, status: :unprocessable_entity } 
    end 
    end 

    # ... 

    private 

    def comment_params 
     params.require(:comment).permit(:body) 
    end 

    def set_improvement_action 
     @improvement_action = ImprovementAction.includes(:comments) 
           .find(params[:improvement_action_id]) 
    end 

end 

Sie sollten das Seeding mit neuen Datensätzen auf der Steuerungsseite nach Möglichkeit behandeln.

<%= form_for([@improvement_action, @comment]) do |f| %> 
    <div class="field"> 
    <%= f.label :body %><br> 
    <%= f.text_area :body %> 
    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 
+0

Danke für die Hilfe :) so gibt mir diesen Fehler: ArgumentError in PerformanceIndicators # zeigen Anzeigen C: /.../ app/views/comments/_form .html.erb wo Zeile # 1 erhöht: Erstes Argument in Form nicht gleich Null enthalten oder leer sein –

+0

Wenn Sie es in Ihrer Show Aktion verwenden möchten Sie festlegen müssen '@comment = @ improvement_action.comments.new' in der Controller oder ändern Sie das Formular in '[@improvement_action, @comment || @ improvement_action.comments.new] ' – max

+0

es gibt mir wieder den ersten Fehler: undefined Methode' Kommentare 'für nil: NilClass –

Verwandte Themen