Как мне справиться с ошибкой авторизации из-за неправильного именования контроллеров? - PullRequest
0 голосов
/ 08 декабря 2010

У меня в приложении 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

Ответы [ 2 ]

2 голосов
/ 08 декабря 2010

В подобных ситуациях мне нравится создавать метод контроллера, который я могу переопределить при необходимости. Например:

# 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 голос
/ 08 декабря 2010

Казалось бы, переменная экземпляра @box_wod не создается до тех пор, пока не будет вызван метод require_owner, поэтому current_user_is_owner? проверяет нулевое значение, в результате чего оно всегда возвращает false. Возможно, вам нужен еще before_filter для заполнения переменной экземпляра до вызова require_owner.

...