我正在尝试将gem devise
实施到我的应用中。
在此之前,我的顶级模特是Album
,但现在是belongs_to :user
(来自设计)。
然后我添加到了albums_controller.rb:
before_action :authenticate_user!
效果很好 - 用户必须从现在开始登录。现在我希望他能够在他的范围内完成所有相册。我发现那种方法的存在:
def index
@albums = Album.all
end
我可以使用:
@albums = current_user.albums
以及我所拥有的每种方法。我想知道是否有更好的方法 - 将current_user
设置为相册控制器中每个操作/方法的默认范围。然后我找到了一些有趣的东西here。我可以将它添加到Album的模型中,但我不确定where
的最佳costruct current_user
子句。也许是这样的:
class Album < ActiveRecord::Base
default_scope where(:user_id => current_user.id)
end
我甚至不确定这是否正确。我很感激你的意见。
答案 0 :(得分:4)
您应该只使用常规命名范围:
scope :for_user, lambda{ |user| where(:user_id => user.id) }
然后在你的控制器中替换
带有@albums = Album.all
的 @albums = Album.for_user(current_user)
虽然理论上你可以将arguments传递给你的默认范围,但以上是首选方法。
答案 1 :(得分:4)
我不确定你为什么要这样做。最好的方法是使用控制器来确定模型的范围。这种类型的东西不属于该模型。
def index
@albums = current_user.albums
end
如果要避免重复,请创建检索对象的方法。所以不要这样:
def show
@album = current_user.albums.find(params[:id])
end
def edit
@album = current_user.albums.find(params[:id])
end
# etc...
你可以这样做:
def index
albums
end
def show
album
end
def update
if album.update(album_params)
end
# etc...
private
def albums
@albums ||= current_user.albums
end
def album
@album ||= current_user.albums.find(params[:id)
end
您甚至可以使用before_filter
来避免从操作中调用相册方法,但这不是一个好方法。您总是倾向于忘记添加和删除过滤器中的操作。
before_action :set_album, only: [:show, :edit, :update, :destroy]
def set_album
@album ||= current_user.albums.find(params[:id])
end
然后在一个地方创建实例变量。正如@wacaw建议的那样,如果这对您有吸引力,您可以进一步使用decent_exposure gem。就个人而言,我很高兴停在控制器上并在我的视图中使用实例方法。
如果您有更复杂的授权需求,我建议您使用pundit或cancan,尽管后者似乎没有得到积极维护。
Rails Casts上的decent_exposure还有更多内容。如果您真的喜欢这种类型的范围,请查看此Rails Cast on Multitenancy with Scopes。但这适用于拥有许多用户而非单个用户的组织。
答案 2 :(得分:1)
使用帮助程序在控制器中创建声明性接口
https://github.com/voxdolo/decent_exposure
设计示例:
http://railscasts.com/episodes/259-decent-exposure?view=comments#comment_151102
答案 3 :(得分:0)
您可以使用inherited_resources gem来保持控制器清除样板代码。以下代码是构建标准CRUD控制器所需的一切,该控制器自动范围为current_user
并检查身份验证。
class AlbumsController < InheritedResources::Base
before_action :authenticate_user!
protected
def begin_of_association_chain
current_user
end
end