Ruby on rails 通过父记录更新关联的记录更好还是单独更新更好?

Ruby on rails 通过父记录更新关联的记录更好还是单独更新更好?,ruby-on-rails,activerecord,associations,Ruby On Rails,Activerecord,Associations,假设我们有一篇文章和一篇评论模型。我们的路线设置如下: # routes.rb resources :articles do resources :comments end 现在,我们可以通过CommentController销毁注释,但我看到有许多方法已经实现 # method 1 def destroy Comment.where(article_id: params[:article_id]).find(params[:id]).destroy end # method 2 d

假设我们有一篇
文章
和一篇
评论
模型。我们的路线设置如下:

# routes.rb
resources :articles do
  resources :comments
end
现在,我们可以通过
CommentController
销毁
注释
,但我看到有许多方法已经实现

# method 1
def destroy
  Comment.where(article_id: params[:article_id]).find(params[:id]).destroy
end

# method 2
def destroy
  Comment.find(params[:id]).destroy
end

# method 3
def destroy
  article = Article.find(params[:article_id])
  comment = article.comments.find(params[:id])
  comment.destroy
end
哪一个更好?为什么?


我在以前的剧集和博客中看到,出于“安全”的原因,或者因为更好的做法是确保
评论只能在各自的
文章中找到,所以我们应该使用前者,但为什么这样更好呢?我无法找到任何深入到答案中的东西。

当您以这种方式处理嵌套数据时,最好在父项下确定模型查找范围,以避免人们以过于简单的方式迭代ID。您通常不希望这样做,如果这是一种习惯,它将保护您免受更严重的安全问题的影响

例如,假设您对文章具有某种可见性权限。使用方法2,可以使用允许您查看的
文章id
来访问您没有看到的评论


方法1和3表面上做的是相同的事情,但我更喜欢方法1,因为它使用较少的数据库访问。

这取决于用例。过度嵌套的路由可能被视为一种代码气味,而这种安全动机充其量也令人怀疑。听起来应该由授权层来处理。非嵌套路由和控制器不那么复杂,并且避免了必须传递第二个参数的需要。绝对不是方法2。除非您仔细检查用户是否有权访问该注释的销毁操作,否则他可以简单地修改HTML,替换注释的id并销毁其他人的注释。通常,第三种方法最好与before_操作结合使用,该操作为CommentsController的所有操作设置
@article
变量