由于控制器命名错误,如何处理授权打嗝?

时间:2010-12-07 22:23:39

标签: ruby-on-rails ruby model-view-controller controller authorization

我的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_controllerposts_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

2 个答案:

答案 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之前填充实例变量。