我真的想开始学习Rails最佳实践,特别是遵循“胖模型,瘦模控制器”逻辑。
说我有以下评论控制器
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(comment_params)
@comment.user_id = current_user.id if current_user
@comment.save!
if @comment.save
redirect_to post_path(@post)
else
render 'new'
end
end
def edit
@post = Post.find(params[:post_id])
@comment = @post.comments.find(params[:id])
end
def update
@post = Post.find(params[:post_id])
@comment = @post.comments.find(params[:id])
if @comment.update(params[:comment].permit(:comment))
redirect_to post_path(@post)
else
render 'Edit'
end
end
def destroy
@post = Post.find(params[:post_id])
@comment = @post.comments.find(params[:id])
@comment.destroy
redirect_to post_path(@post)
end
private
def comment_params
params.require(:comment).permit(:comment)
end
开始重构代码的好地方是什么? 我想我立即将编辑和更新中的 @post 和 @comment 改为单独的方法,然后在方法上调用 before_action 。但这仍然是将所有代码都放在控制器中。
是否有任何代码可以移动到模型中?如果是这样,我应该如何构建它们呢?
答案 0 :(得分:1)
此代码没有太大的改进空间,这是一个基本的问题,这里有一个像你建议的before_action的例子
before_action :load_post_and_comment, only: %i(edit update destroy)
def load_post_and_comment
@post = Post.find(params[:post_id])
@comment = @post.comments.find(params[:id])
end
还有其他一些注释
def create
# ...
@comment.save!
if @comment.save
# ...
else
# ..
end
end
在此版本中,你应该删除额外的@comment.save!
,你只需要保存一次。
def update
# ...
if @comment.update(params[:comment].permit(:comment))
# ...
else
# ...
end
end
您已经拥有comment_params
方法,使用它,因为如果您在任何时候为评论添加新属性,您将更新该方法,但您可能会忘记此部分和在你注意到你也需要在这里允许之前,你会得到错误的错误。
答案 1 :(得分:0)
如果你想真的全力以赴的瘦控制器模型,那就有这个宝石:https://github.com/NullVoxPopuli/skinny_controllers
在哪里,您可以这样配置CommentsController
:
class CommentsController < ApplicationController
include SkinnyControllers::Diet
def create
if model.errors.present?
render 'new'
else
redirect_to post_path(model)
end
end
def update
redirect_to post_path(model)
end
# ... etc
private
def comment_params
params.require(:comment).permit(:comment)
end
end