我正在构建一个JSON api,它将成为另一个rails站点的数据源(使用devise for auth),并且具有基本令牌认证功能。 API还将负责向移动应用程序提供数据。
在API中,我有以下模型: 用户,书籍和章节 用户has_many:书籍,书籍has_many:章节。在我的路线文件中,我有
shallow do
resources :users do
resources :books do
resources :chapters
end
end
end
这会产生如下路线:
/users/:user_id , /users/:user_id/books
/books/:book_id , /books/:book_id/chapters
/chapters/:chapter_id
ie'浅路线'而不是/ users /:user_id / books /:book_id / chapters /:chapter_id
我想知道我应该如何对这些进行身份验证,因为这一章并不属于用户。这不仅仅是检查user_id的情况(因为这是书籍模型的一个属性) )。
# chapters_controller
def show
@chapter = Chapter.find(params[:id])
end
我是否必须获取@ chapter的书,然后检查其user_id? 某种程度上对我来说并不合适。我是朝着错误的方向前进的吗?
感谢阅读!
答案 0 :(得分:1)
我发现一种技术可以让控制器建立一个模型范围,限制当前经过身份验证的用户可见/可更新/可销毁的内容。
我首先使用request_store gem在我的User
模型上从我的控制器设置当前用户和请求信息,这只是一个小的垫片,比线程本地存储有点清理。
这可以通过User
课程从我的任何模型中获取用户和请求信息。我可以在任何需要的地方使用User.current
,User.request
和User.location
。
您的控制器只需在对用户进行身份验证后设置User.current
和User.request
即可。这在构建模型中的范围时非常有用,因为它们可以限制当前用户可以访问的范围。
您可以在模型上定义范围,例如visible
,可以在相关模型上执行where(:owner => User.current.id)
或类似操作,以限制当前模型的可见/可更新/可销毁的内容。
然后您的控制器只需调用SomeModel.visible
,SomeModel.updateable
,SomeModel.destroyable
,它将获得一个限制为可读/写/销毁的范围。基于该模型范围的任何find
只有在模型确实在用户的范围规则范围内时才会成功!
示例用户模型:
# models/user.rb
require 'request_store'
class User
def self.current
RequestStore.store[:current_user]
end
def self.current=(user)
RequestStore.store[:current_user] = user
end
def self.request
RequestStore.store[:current_request]
end
def self.request=(request)
# stash the request so things like IP address and GEO-IP based location is available to other models
RequestStore.store[:current_request] = request
end
def self.location
# resolve the location just once per request
RequestStore.store[:current_location] ||= self.request.try(:location)
end
end