下面的动作会创建一个新评论。
如何优化此操作,以便head 401 and return
不会重复多次。
def create
@user = User.where(id: params[:user_id]).first
if @user
if current_user.friend_with?(@user) or current_user == @user
@status = @user.statuses.where(id: params[:status_id]).first
if @status
@comment = @status.comments.build(params[:comment])
@comment.owner = current_user
if @comment.valid?
@comment.save
current_user.create_activity(:comment_status, @comment, @user)
else
head 401 and return
end
else
head 401 and return
end
else
head 401 and return
end
else
head 401 and return
end
end
谢谢。
答案 0 :(得分:2)
您的代码中有大量过多的检查和分支,因此可以简化为:
def create
success = false
@user = User.find(params[:user_id])
current_user_is_friend = current_user.friend_with?(@user) || current_user == @user
if @user && current_user_is_friend && @status = @user.statuses.find(params[:status_id])
@comment = @status.comments.build(params[:comment])
@comment.owner = current_user
if @comment.save
current_user.create_activity(:comment_status, @comment, @user)
success = true
end
end
render(status: 401, content: '') unless success
end
我做过的一些事情:
if
条件,因为没有必要将它们分开。where(id: ...).first
更改为find(...)
,因为它们是相同的。请注意,如果find
失败,它将给出404.这可能更有意义,但是(我认为确实如此)@comment.valid?
,因为如果对象无效,@comment.save
会返回save
。false
代替||
作为布尔逻辑(they're not the same)。or
代替render(status: ..., content: '')
。我建议您尝试将一些逻辑推入模型中。例如,head ... and return
如果传递给同一个用户,则应该返回true。
答案 1 :(得分:2)
您想何时返回401
?
您可以使用引发异常的方法,而不是使用这么多条件。执行此操作时,您可以使用所需行为(渲染401
)来拯救这些异常。
所以我对列出条件的建议是:
find!
代替where
,然后使用first
。raise
,最好是自定义异常(NotAFriendError
)find!
create!
,它等同于new
,然后是save!
,如果验证失败,将会引发ActiveRecord::RecordInvalid
异常。结果如下:
def create
begin
@user = User.find!(params[:user_id])
raise unless current_user.friend_with?(@user) || current_user == @user
@status = @user.statuses.find!(params[:status_id])
@comment = @status.comments.
create!(params[:comment].merge(:owner => current_user))
rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
head 401
end
# everything went well, no exceptions were raised
current_user.create_activity(:comment_status, @comment, @user)
end
答案 2 :(得分:0)
def create
@user = User.where(id: params[:user_id]).first
if @user
if current_user.friend_with?(@user) or current_user == @user
@status = @user.statuses.where(id: params[:status_id]).first
if @status
@comment = @status.comments.build(params[:comment])
@comment.owner = current_user
if @comment.valid?
@comment.save
current_user.create_activity(:comment_status, @comment, @user)
everythingOK = true
end
end
end
end
head 401 and return unless everythingOK
end