Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:深层嵌套资源给出错误:未定义方法';评论';_Ruby On Rails_Nested_Comments_Nested Forms - Fatal编程技术网

Ruby on rails Rails:深层嵌套资源给出错误:未定义方法';评论';

Ruby on rails Rails:深层嵌套资源给出错误:未定义方法';评论';,ruby-on-rails,nested,comments,nested-forms,Ruby On Rails,Nested,Comments,Nested Forms,我在rails应用程序中遇到了这个错误未定义的方法“comments”。我知道我不应该执行>级别1嵌套资源,但我不知道如何在这种情况下应用正确的方法 目前这是我的路线: resources :performance_indicators do resources :improvement_actions do member do put "like" => "improvement_actions#upvote" put "unlike

我在rails应用程序中遇到了这个错误
未定义的方法“comments”
。我知道我不应该执行>级别1嵌套资源,但我不知道如何在这种情况下应用正确的方法

目前这是我的路线:

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
正如我所说,我得到了这个错误:

NoMethodError in PerformanceIndicators#show
Showing .../app/views/comments/_form.html.erb where line #1 raised:
undefined method `comments' for nil:NilClass
我不知道我的问题是否出在控制器上。有人能帮忙吗?:)

编辑:

我的评论/表格:

    <%= 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 %>


这是我的评论控制器:

    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
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
class CommentsController
以下是我的性能指示或控制器:

    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
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
类性能指示器控制器
让我们从修复深嵌套开始

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:[]
是一个聪明的技巧,它将路由嵌套在资源下,但抑制路由的生成。我们需要它,因为第一个块实际上声明了我们需要的所有路由

                                       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
取消这些资源的嵌套意味着需要跨越的障碍将大大减少

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
类注释