Контроллеры пространства имен Rails 3.2.3 переопределяются глобальными контроллерами с тем же именем

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

class ApplicationController < ActionController::Base
 protect_from_forgery
end

И контроллер приложения с пространством имен выглядит так:

class Admin::ApplicationController < ApplicationController

def authenticate_admin!
 if current_admin.nil?
  redirect_to new_admin_session_url
 end
end

private

 def current_admin
  @current_admin ||= Admin.find(session[:admin_id]) if session[:admin_id]
 end

helper_method :current_admin
end

Когда мы используем before_filter "authenticate_admin!" нравится:

class Admin::AssetsController < Admin::ApplicationController
  before_filter :authenticate_admin!
end

Выдается ошибка «NoMethodError in Admin::AssetsController#new». Это происходит только тогда, когда мы попадаем на глобальный маршрут перед маршрутом в пространстве имен. Если сервер перезапускается и сначала загружается маршрут с пространством имен, все работает правильно.


person Bryan Ashley    schedule 05.06.2012    source источник
comment
В каких файлах находятся эти контроллеры?   -  person Frederick Cheung    schedule 05.06.2012
comment
app/controllers/admin/application_controller.rb, app/controllers/admin/assets_controller.rb и app/controllers/application_controller.rb   -  person Bryan Ashley    schedule 05.06.2012


Ответы (2)


Это происходит потому, что у вас также есть модель Admin (класс) с тем же именем, что и ваше пространство имен.

Эта ветка группы Google дает хорошее объяснение того, что именно происходит.

Чтобы исправить это, я бы либо переименовал модель в AdminUser, либо, если это невозможно, переименование пространства имен также решит проблему.

person Bart Jedrocha    schedule 05.06.2012

Контроллеры с пространством имен должны отображаться в правильной структуре каталогов.

app/controllers/admin/application_controller.rb

app/controllers/admin/assets_controller.rb

Лично я бы посоветовал не перегружать имя ApplicationController для базового контроллера с пространством имен. Это не вызовет проблемы, но это вопрос предпочтений - есть только одно приложение, и должно быть только одно ApplicationController. Вы можете использовать ContentManagementController, если это цель пространства имен Admin.

Во-вторых, лучше использовать ключевое слово module и определять свои контроллеры следующим образом:

module Admin
  class ContentManagementController < ApplicationController
      # ..
  end
end

# app/controllers/admin/content_management_controller.rb

редактировать: я также только что увидел конкретную ошибку (может быть, ваш вопрос был обновлен?) - вам нужно определить новое действие на AssetsController

def new
   #
end
person brentvatne    schedule 05.06.2012
comment
Извините, я не упомянул об этом раньше; контроллеры находятся в правильной структуре каталогов, названных точно так, как вы указали. У нас есть экшены в AssetsController, просто мы не поместили их в исходный пост, так как это показалось неуместным. - person Bryan Ashley; 05.06.2012