У меня есть движок (разработанный мной / компанией, в которой я работаю), который мы используем в нескольких разных проектах.Я только что преобразовал его для работы с rails 3.1 с конвейером ресурсов, и все, кажется, работает ... по большей части.
Моя проблема в том, что мне нужно расширить функциональность UsersController
с помощьюнемного специй для конкретного приложения, но я не уверен, как лучше это сделать.Движок не определяет действие Users#show
, но это приложение нуждается в нем, поэтому я добавил в файл маршрутов:
JobEngine::Application.routes.draw do
root :to => 'home#index'
resource :users, :only => [:show]
resources :jobs, :only => [:show]
end
Затем в своем приложении я создал UsersController:
class UsersController < MyEngine::UsersController
def show
end
end
Затем я сделал users/show.html.haml
представление, я сократил его, чтобы показать только одну из проблемных строк:
= link_to "Somewhere", job_path(3)
Это дает мне ошибку, которая читает undefined method 'job_path' for #<#<Class:0x00000102d69900>:0x00000102d4ed30>
Что странно, потому что до я заставил UsersController
своего приложения наследовать от MyEngine::UsersController
, оно работало просто отлично.
Когда я выполняю rake routes
в консоли, появляются следующиелинии:
users GET /users(.:format) {:action=>"show", :controller=>"users"}
job GET /jobs/:id(.:format) {:action=>"show", :controller=>"jobs"}
Я могу изменить определение класса следующим образом:
class UsersController < ApplicationController
, и тогда ссылка будет работать нормально.Однако контроллер двигателя MyEngine::UsersController
уже наследуется от ApplicationController
.Я могу поместить код в ApplicationController
моего приложения (например, before_filter
), и он будет работать, как и ожидалось, поэтому я знаю, что мое определение класса в конечном итоге попадает в ApplicationController
моего приложения, почему помощник job_path не работает?
Когда я изменяю действие show на следующее:
def show
job_path(3)
end
Я получаю ошибку:
ActionController::RoutingError (No route matches {:action=>"show", :controller=>"jobs", :id=>3}):
app/controllers/users_controller.rb:9:in `show'
Что еще больше смущает меня, потому что теперь он действительно распознает job_path как метод,но почему-то маршрутизатор не определяет, куда идти со всеми правильными параметрами.
Что я делаю не так?Как правильно расширить функциональность контроллера двигателя?Я видел вопрос о функциональности расширяющего движка здесь.
И последовал этому примеру кода, изменив определение моего класса, вместо этого заново открыв MyEngine::UsersController
, но я все еще получаю те же самые результаты, касающиеся job_path(NUMBER)
ОБНОВЛЕНИЕ:
Хорошо, я вроде понял, что происходит.Допустим, у вашего движка есть маршрут job_path, а у вашего приложения - маршрут job_path.Если вы находитесь на странице, к которой обращались через контроллер движка, вы можете вызвать помощника движка просто с помощью job_path
, но вы также можете вызвать помощника основного приложения с помощью main_app.job_path
.
Аналогично, есливы находитесь на странице, доступ к которой осуществляется через один из контроллеров вашего приложения, вы получаете доступ к помощнику движка с помощью my_engine.job_path
и помощнику вашего собственного приложения с помощью job_path
.Это предполагает, что у вас есть что-то вроде mount MyEngine::Engine => "/my_engine", :as => 'my_engine'
.
Когда вы наследуете контроллер двигателя из своего приложения, он затем полностью меняет ваши помощники маршрута, чтобы думать, что вы находитесь в контексте двигателя через контроллер /просмотреть жизненный цикл.Таким образом, чтобы решить мою проблему, все, что мне действительно нужно сделать, это изменить ее на main_app.job_path(3)
, и она работает.
Я не полностью удовлетворен этим решением, потому что оно кажется немного ... странным.Возможно, у меня есть часть на этой странице, которая будет использоваться на отдельной не наследуемой странице.Теперь помощник по ссылкам будет работать только для одной из двух страниц, но никогда не для обеих = \ Я что-то здесь упустил ...?