这是我目前在 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,这将命中数据库。