我的Ruby on Rails应用程序似乎有授权打嗝。我一直在我的应用程序控制器中使用以下方法,它一直工作得很漂亮。
def require_owner
obj = instance_variable_get("@#{controller_name.singularize.camelize.underscore}") # LineItem becomes @line_item
return true if current_user_is_owner?(obj)
render_error_message("You must be the #{controller_name.singularize.camelize} owner to access this page", root_url)
return false
end
然后我通过以下方式过滤特定的控制器:
before_filter :require_owner, :only => [:destroy, :update, :edit]
我最近创建了一个新的控制器,它有一些不同的命名约定,似乎导致了问题。通常我的控制器会显示messages_controller
或posts_controller
。在这个特定情况下,我命名了生成box_wod
的资源box_wods_controller
。
这是唯一一个看起来有这个过滤器问题的控制器,所以我打赌我可以告诉它是在它的命名中,因此application_controller
方法没有识别记录的所有者。
我没有收到错误消息但应用程序不允许我编辑,更新或销毁记录,因为我不是BoxWod owner
。我的路由和我的关联一样正确,并且正确的信息被传递到box_wod
表。
有没有办法重写application_controller
方法以识别box_wod
资源中的附加下划线?或者这甚至是我的问题?
更新:
以下是BoxWodsController中的三种方法:
def edit
@workout_count = Workout.count
@box_wod = BoxWod.find(params[:id])
end
def update
@box_wod = BoxWod.find(params[:id])
respond_to do |format|
if @box_wod.update_attributes(params[:box_wod])
flash[:notice] = 'BoxWod was successfully updated.'
format.html { redirect_to(@box_wod) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @box_wod.errors, :status => :unprocessable_entity }
end
end
end
def destroy
@box_wod = BoxWod.find(params[:id])
@box_wod.destroy
respond_to do |format|
format.html { redirect_to(box_wods_url) }
format.js
end
end
答案 0 :(得分:2)
在这种情况下,我喜欢创建一个可以在必要时覆盖的控制器方法。例如:
# application_controller.rb
class ApplicationController
def require_owner
obj = instance_variable_get("@#{resource_instance_variable_name}")
# Do your authorization stuff
end
private
def resource_instance_variable_name
controller_name.singularize.camelize.underscore
end
end
# box_wods_controller.rb
class BoxWodsController
private
def resource_instance_variable_name
'box_wod' # Or whatever your instance variable is called
end
end
最后,请发布您的BoxWodsController
代码,以便我们更好地诊断问题。
答案 1 :(得分:1)
在调用@box_wod
方法之前,似乎不会创建require_owner
实例变量,因此current_user_is_owner?
正在检查nil值,导致它始终返回false。也许你需要另一个before_filter来在调用require_owner
之前填充实例变量。