在注释控制器中创建方法时遇到问题



这是我目前在 CommentsController 中创建的方法

def create
   @place = Place.find(params[:place_id])
   @comment = @place.comments.create(comment_params)
   @comment.user = current_user
 if @comment.save
  redirect_to place_path(@place)
 else
  render "comments/_form"
 end
end

有人告诉我,这会两次命中数据库。检查日志后,结果如下:

Started GET "/places/9" for 127.0.0.1 at 2015-01-22 15:01:47 -0800
Processing by PlacesController#show as HTML
Parameters: {"id"=>"9"}
Place Load (0.3ms)  SELECT  "places".* FROM "places"  WHERE       "places"."id" = ? LIMIT 1  [["id", 9]]
Comment Load (0.2ms)  SELECT "comments".* FROM "comments"  WHERE "comments"."place_id" = ?  [["place_id", 9]]
User Load (0.2ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ? LIMIT 1  [["id", 2]]
CACHE (0.0ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ?    LIMIT 1  [["id", 2]]
CACHE (0.0ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ?   LIMIT 1  [["id", 2]]
CACHE (0.0ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ?    LIMIT 1  [["id", 2]]
Rendered comments/_comment.html.erb (8.0ms)
Rendered comments/_form.html.erb (2.7ms)
Rendered places/show.html.erb within layouts/application (73.3ms)
User Load (0.2ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ? LIMIT 1  [["id", 2]]
Completed 200 OK in 532ms (Views: 529.4ms | ActiveRecord: 1.0ms)

所以很明显,我不想在我的代码中效率低下。

这是该人的建议:

comment_params[:user_id] = current_user.id
if @places.comments.create(comment_params)
   .....
else 
    ....
end

所以。。。我将 Create 方法重写为:

 def create
   @place = Place.find(params[:place_id])
   @comment = @place.comments.create(comment_params)
   comment_params[:user_id] = current_user.id
  if @places.comments.create(comment_params)
   redirect_to place_path(@place)
  else
   render "comments/_form"
  end
 end

在重写的 Create 方法上,当我尝试发表评论时,我不断收到此错误:undefined method comments for nil:NilClass

请帮助我了解如何正确重写此创建方法?

旁注 - 不确定它是否相关,如果是,请解决它,如果没有,请忽略

在检查rails控制台中的最后一条评论时,我惊讶地发现user_id为,而对于地方来说,则不是。

地点属于用户评论属于用户

用户有许多地方和评论

您调用create两次,这将导致评论被发布两次,这可能不是您的意图。

第一次调用 create 时,它没有分配user_id,这就是数据库中user_id设置为 null 的原因(提示:对注释模型中的user_id使用状态验证)。

第二次调用 create 时,您会在 @places 而不是@place(拼写错误)上调用它。这会导致您的 nil 错误。

这是解决问题的另一种方法:

 def create
   @place = Place.find(params[:place_id])
   @comment = @place.comments.build(comment_params)
   @comment.user_id = current_user.id
   if @comment.save(comment_params)
     redirect_to place_path(@place)
   else
     render "comments/_form"
   end
 end

不同之处在于,我们首先"构建"评论而不创建它,但它将填充该地点的 ID 等。

在下一步中,我们添加当前用户的 id,然后在对象上调用 save,这将命中数据库。

最新更新