我有以下代码:
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))
最好在受保护的方法中单独处理。我需要怎样以及为什么要这样做?
答案 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
方法中编写该代码。方法destroy
,plot.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