I'm making a small rails engine which I mount like this:
mount BasicApp::Engine => "/app"
Using this answer I have verified that all the routes in the engine are as the should be:
However - when I (inside the engine) link to a named route (defined inside the engine) I get this error
undefined local variable or method `new_post_path' for #<#<Class:0x000000065e0c08>:0x000000065d71d0>
Running "rake route" clearly verifies that "new_post" should be a named path, so I have no idea why Rails (3.1.0) can't figure it out. Any help is welcome
my config/route.rb (for the engine) look like this
BasicApp::Engine.routes.draw do resources :posts, :path => '' do resources :post_comments resources :post_images end end
I should add that it is and isolated engine. However paths like main_app.root_path works fine - while root_path does not
Rails RESTful Design which creates seven routes all mapping to the user controller. Rails also allows you to define multiple resources in one line.
Mount within the Rails routes does the equivalent of a Unix mount . It actually tells the app that another application (usually a Rack application) exists on that location. It is used mostly for Rails Engines.
Well, simply put a Rails engine is the miniature edition of a Rails application. It comes with an app folder, including controllers, models, views, routes, migrations... The difference though is, that an engine won't work on its own.
I believe the best solution is to call new_post_path
on the Engine's routes proxy, which is available as a helper method. In your case, the helper method will default to basic_app_engine
, so you can call basic_app_engine.new_post_path
in your views or helpers.
If you want, you can set the name in one of two ways.
# in engine/lib/basic_app/engine.rb: module BasicApp class Engine < ::Rails::Engine engine_name 'basic' end end
or
# in app/config/routes.rb: mount BasicApp::Engine => '/app', :as => 'basic'
In either case, you could then call basic.new_posts_path
in your views or helpers.
Another option is to not use a mounted engine and instead have the engine add the routes directly to the app. Thoughtbot's HighVoltage does this. I don't love this solution because it is likely to cause namespace conflicts when you add many engines, but it does work.
# in engine/config/routes.rb Rails.application.routes.draw do resources :posts, :path => '' do resources :post_comments resources :post_images end end # in app/config/routes.rb: # (no mention of the engine)
On Rails 4 the engine_name
directive did not work for me.
To access a named route defined in engine's routes from engine's own view or controller, I ended up using the verbose
BasicApp::Engine.routes.url_helpers.new_post_path
I recommend defining a simple helper method to make this more usable
# in /helpers/basic_app/application_helper.rb module BasicApp::ApplicationHelper def basic_app_engine @@basic_app_engine_url_helpers ||= BasicApp::Engine.routes.url_helpers end end
With this in place you can now use
basic_app_engine.new_post_path
In case you need to access your main application helper from the engine you can just use main_app
:
main_app.root_path
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With