JSON API:如何确定资源属于current_user?

JSON API: How to make sure a resource belongs to current_user?

在 JSON API 结构方面需要一些帮助。

假设我们有以下内容:

class User < ApplicationRecord
 has_many :posts
end

class Post < ApplicationRecord
 has_many :comments
 belongs_to :user
end

class Comment < ApplicationRecord
 belongs_to :post
 has_many :talkbacks
end

class Talkbacks < ApplicationRecord
 belongs_to :comment
end

现在,api 分应该是这样的:

/posts
/posts/:id
/posts/:id/comments
/comments
/comments/:id
/comments/:id/talkbacks
/talkbacks
/talkbacks/:id

如果我们想显示 post,假设我们有令牌,确保 post 属于当前用户很容易:

# /posts/:id
current_user.posts.find_by_id!(params_id)

但是,如果我们要显示特定的对讲,则很难确定该对讲是否属于用户:

# /talkbacks/:id

确保用户可以访问该对讲的最佳方式是什么?

您可以尝试这样的操作:

talkback = Talkback.find(params[:id])
if talkback
  if talkback.comment.post.user == current_user
    # do stuff
  else
    # talkback doesn't belong to signed in user
  end
else
  # no talkback exists with that id in the database
end

或者您可以将该逻辑封装在模型中并使用如下方法:

talkbacks_controller.rb

talkback = Talkback.find(params[:id])
if talkback
  if talkback.belongs_to_user?
    # do stuff
  else
    # talkback doesn't belong to signed in user
  end
else
  # no talkback exists with that id in the database
end

talkbalk.rb(型号class)

def belongs_to_user?(user = current_user)
  self.comment.post.user == user
end

如果未指定该方法的参数,则此方法使用当前登录用户作为默认用户。

为什么不直接将 user_id 添加到对讲 table 中,然后设置它们之间的关联。我认为这样做会让你的生活更轻松,然后尝试进行深层嵌套调用。 (我还会考虑将 Talkbacks class 的名称更改为单数 "Talkback",以便您坚持 Rails 的命名约定。)

class User < ApplicationRecord
  has_many :posts
  has_many :talkbacks
end

class Talkback
  belongs_to :comment
  belongs_to :user
end

那你就可以拨打了:

# /talkbacks/:id
current_user.talkbacks.find_by_id!(params_id)

您可以通过 has_many :through 完成此操作。 看看这个post.

你应该用 has_one, through 关系充实你的关系。然后,很容易执行查询。您不需要将 user_id 添加到任务字段(并且不应该,因为 post 应该处理该关联)。 has_one 关系允许您通过另一个模型有效地拥有 belongs_to 关系,并且无需连接 table.

class User < ApplicationRecord
  has_many :posts
  has_many :comments, through: :posts
  has_many :talkbacks, through: :comments
end

class Post < ApplicationRecord
  belongs_to :user

  has_many :comments
  has_many :tasks, through: :comments
end

class Comment < ApplicationRecord
  belongs_to :post

  has_one :user, through: :post

  has_many :talkbacks
end

class Talkbacks < ApplicationRecord
  belongs_to :comment

  has_one :user, through: :comment
end

然后你可以在你的控制器中做,

current_user.talkbacks.find(params[:id])

作为旁白在你的 post...

current_user.posts.find_by_id!(params_id)

posts.find_by_id!() 相当于 posts.find() 所以你不需要做 by_id! 部分。默认情况下,Rails 如果无法使用 find 方法找到记录,将引发异常,与在 find_by_id 方法上使用 bang 相同。