我有许多资源(旅行,计划等),其行动应仅限于资源的所有者.
如何使用ApplicationController中定义的#require_owner方法实现代码来实现此目的?理想情况下,代码将查找所有者的继承链,因此before_filter将处理:belongs_to:travel that belongs_to:user的注释.
class TripsController < ApplicationController belongs_to :member before_filter :require_owner ... end
autodata.. 5
我没有完全按照描述(评论真的归旅行老板所有吗?),但稍微扩展jonnii的答案,这是一个限制行程控制器的例子:
class ApplicationController < ActionController::Base ... protected # relies on the presence of an instance variable named after the controller def require_owner object = instance_variable_get("@#{self.controller_name.singularize}") unless current_user && object.is_owned_by?(current_user) resond_to do |format| format.html { render :text => "Not Allowed", :status => :forbidden } end end end end class TripsController < ApplicationController before_filter :login_required # using restful_authentication, for example # only require these filters for actions that act on single resources before_filter :get_trip, :only => [:show, :edit, :update, :destroy] before_filter :require_owner, :only => [:show, :edit, :update, :destroy] ... protected def get_trip @trip = Trip.find(params[:id]) end end
假设模型看起来像这样:
class Trip < ActiveRecord::Base belongs_to :owner, :class_name => 'User' ... def is_owned_by?(agent) self.owner == agent # or, if you can safely assume the agent is always a User, you can # avoid the additional user query: # self.owner_id == agent.id end end
该login_required
方法(由restful_authentication或authlogic提供或依赖auth插件)确保用户登录并为用户提供current_user
方法,get_trip
设置trip实例变量,然后检入该变量require_owner
.
如果模型已经实现了该is_owned_by?
方法,则该相同模式可以适用于任何其他资源.如果您在资源是注释时尝试检查它,那么您将在CommentsController
:
class CommentsController < ApplicationController before_filter :login_required # using restful_authentication, for example before_filter :get_comment, :only => [:show, :edit, :update, :destroy] before_filter :require_owner, :only => [:show, :edit, :update, :destroy] ... protected def get_comment @comment = Comment.find(params[:id]) end end
使用Comment
看起来像这样的模型:
class Comment < ActiveRecord::Base belongs_to :trip # either # delegate :is_owned_by?, :to => :trip # or the long way: def is_owned_by?(agent) self.trip.is_owned_by?(agent) end end
确保在执行此操作时检查日志,因为如果您不小心,依赖关联的检查可能会导致大量查询.
我没有完全按照描述(评论真的归旅行老板所有吗?),但稍微扩展jonnii的答案,这是一个限制行程控制器的例子:
class ApplicationController < ActionController::Base ... protected # relies on the presence of an instance variable named after the controller def require_owner object = instance_variable_get("@#{self.controller_name.singularize}") unless current_user && object.is_owned_by?(current_user) resond_to do |format| format.html { render :text => "Not Allowed", :status => :forbidden } end end end end class TripsController < ApplicationController before_filter :login_required # using restful_authentication, for example # only require these filters for actions that act on single resources before_filter :get_trip, :only => [:show, :edit, :update, :destroy] before_filter :require_owner, :only => [:show, :edit, :update, :destroy] ... protected def get_trip @trip = Trip.find(params[:id]) end end
假设模型看起来像这样:
class Trip < ActiveRecord::Base belongs_to :owner, :class_name => 'User' ... def is_owned_by?(agent) self.owner == agent # or, if you can safely assume the agent is always a User, you can # avoid the additional user query: # self.owner_id == agent.id end end
该login_required
方法(由restful_authentication或authlogic提供或依赖auth插件)确保用户登录并为用户提供current_user
方法,get_trip
设置trip实例变量,然后检入该变量require_owner
.
如果模型已经实现了该is_owned_by?
方法,则该相同模式可以适用于任何其他资源.如果您在资源是注释时尝试检查它,那么您将在CommentsController
:
class CommentsController < ApplicationController before_filter :login_required # using restful_authentication, for example before_filter :get_comment, :only => [:show, :edit, :update, :destroy] before_filter :require_owner, :only => [:show, :edit, :update, :destroy] ... protected def get_comment @comment = Comment.find(params[:id]) end end
使用Comment
看起来像这样的模型:
class Comment < ActiveRecord::Base belongs_to :trip # either # delegate :is_owned_by?, :to => :trip # or the long way: def is_owned_by?(agent) self.trip.is_owned_by?(agent) end end
确保在执行此操作时检查日志,因为如果您不小心,依赖关联的检查可能会导致大量查询.