【问题标题】:Is it better to update an associated record through the parent or by itself?是通过父级更新关联记录还是自己更新关联记录更好?
【发布时间】:2017-08-17 19:07:17
【问题描述】:

假设我们有一个Article 和一个Comment 模型。我们将路线设置为:

# routes.rb
resources :articles do
  resources :comments
end

现在,我们可以通过CommentController 销毁comment,但我已经看到了许多方法。

# 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

哪个更好,为什么?

我在旧的Railscasts 剧集和博客中看到,出于“安全”原因,或者因为最好确保comments 只能在各自的article 中找到,我们应该这样做,但是为什么那个更好吗?我一直无法找到任何深入到答案的内容。

【问题讨论】:

  • 这取决于用例。过度嵌套的路由可以被视为代码异味,而安全动机充其量似乎是可疑的。听起来好像应该处理的是授权层。非嵌套路由和控制器不太复杂,并且无需传递第二个参数。
  • 绝对不是方法 2。除非您仔细检查用户是否可以访问该评论的销毁操作,否则他可以简单地修改 HTML,替换评论的 id 并从其他人。通常,第三种方法是最好的,结合 before_action 为该 CommentsController 的所有操作设置 @article 变量

标签: ruby-on-rails activerecord associations


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多