在受保护方法中添加控制器操作的最佳方法

时间:2015-06-25 07:14:02

标签: ruby-on-rails ruby

我有以下代码:

class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create(params[:comment].permit(:name, :body))
    redirect_to post_path(@post)
  end
  def destroy
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
    @comment.destroy
    redirect_to post_path(@post)
  end
end

我被告知

@comment = @post.comments.create(params[:comment].permit(:name, :body))

最好在受保护的方法中单独处理。我需要怎样以及为什么要这样做?

3 个答案:

答案 0 :(得分:1)

无论你想让简单的东西变得复杂,你都可以尝试:

class CommentsController < ApplicationController
  def create
    deal_and_redirect do
      @post.comments.create(params[:comment].permit(:name, :body))
    end
  end
  def destroy
    deal_and_redirect do
      @post.comments.find(params[:id]).tap { |c| c.destroy }
    end
  end
private
  def deal_and_redirect
    @post = Post.find(params[:post_id])
    @comment = yield if block_given?
    redirect_to post_path(@post)
  end
end

答案 1 :(得分:0)

这些方法不应该是私有的,而应该始终是公开的。但是你可以重构这些方法的大块,并使他们私有如下:

private

您可以在两个或多个方法之间共享的create方法中编写该代码。方法destroyplot.dat <- data.frame(x=c(seq(.8, 1.2, length.out=6), seq(1.8, 2.2, length.out=6)), lb=unlist(c(dat[3,-1], dat[6,-1])), mid=unlist(c(dat[2,-1], dat[5,-1])), ub=unlist(c(dat[1,-1], dat[4,-1]))) plot.dat # x lb mid ub # 1 0.80 8.49 9.27 10.73 # 2 0.88 7.80 8.61 9.31 # 3 0.96 8.50 9.28 10.75 # 4 1.04 6.26 7.00 7.72 # 5 1.12 6.54 6.25 5.98 # 6 1.20 9.11 8.50 7.97 # 7 1.80 10.00 10.76 11.45 # 8 1.88 9.34 10.00 10.00 # 9 1.96 9.25 10.03 11.46 # 10 2.04 7.00 7.75 8.47 # 11 2.12 7.19 6.88 6.58 # 12 2.20 10.12 9.45 8.86 本身应该是公开的,而不是私有的。

答案 2 :(得分:0)

逻辑应当在做太多事情或太长时间时分解为方法。

查看原始实现:

  def create
    # refactor into common method since this needs to be done for all actions anyway
    @post = Post.find(params[:post_id]) 

    # this chunk is doing two things: comment creation and parameter validation
    # each method should only be responsible for one thing
    @comment = @post.comments.create(params[:comment].permit(:name, :body))

    redirect_to post_path(@post)
  end

示例重构

class CommentsController < ApplicationController
  # post needs to be set for all actions since this is a nested route
  before_action :set_post 
  # comment only needs to be set for some actions
  before_action :set_comment, only: [:show, :destroy, :edit, :update]

  def create
    # comment creation belongs within the controller create action
    # param validation should be handled elsewhere
    @comment = @post.comments.create(comment_params)
    redirect_to post_path(@post)
  end

  def destroy
    @comment.destroy
    redirect_to post_path(@post)
  end

  private

  def set_post
    @post = Post.find(params[:post_id])
  end

  def set_comment
    @comment = @post.comments.find(params[:id])
  end

  def comment_params # responsible for controlling what params are permitted
    params.require(:comment).permit(:name, :body)
  end
end