Access url_helper from an Engine class
Asked Answered
E

3

5

I try to access URL helper from inside a Module class. Here's my code :

module Station
  class Plugins

    @@plugins = [] unless defined?(@@plugins) && @@plugins.class == Array

    class << self

      def all
        return @@plugins.sort_by { |p| p[:weight] }
      end

      def register(plugin = {})
        raise "plugin must be a Hash (ie.: `register(:foo => 'bar')`)" unless plugin.class == Hash
        raise "plugin must contain :name (ie.: `register(:name => 'my_plugin')`)" unless plugin[:name].present?
        plugin[:weight] = 1 unless plugin[:weight].present?
        plugin[:href] = eval("#{plugin[:name].downcase.pluralize}_url") unless plugin[:href].present?

        @@plugins.push(plugin) unless @@plugins.include?(plugin)
      end
    end
    # include default plugins: 
    Station::Plugins.register(:name => "Pages", :weight => -1)
  end
end

When I run my server, I got this error back:

undefined local variable or method `pages_url' for Station::Plugins:Class

I read a lot about "how to call url helper from a Class", but none of the solutions I found worked for me.

Extender answered 10/6, 2012 at 10:57 Comment(0)
S
9

Firstly, what you're not making clear is if the url helper you're trying to access is from the parent application the engine is added to, or if it's from another engine this engine has included.

If from parent application, then all you need is:

main_app.pages_url

So you'll need to edit your code accordingly. Note that the "main_app" part is not the name of the parent application but literally the words "main_app".

If you're trying to access a url helper of an engine that you included in this engine, then you need to access it like you would to access any engine from the parent application. I.e.:

Your gemspec file should include:

s.add_dependency('my_engine', path: "~/path/to/my_engine")

routes.rb should include:

mount MyEngine::Engine => "/my_engine", as: "any_name_for_my_engine"

and then access it in your code using:

any_name_for_my_engine.pages_url

Hope this helps.

EDIT: Change your engine's application.rb file to look as shown below, so that you can inherit all the parent application's ApplicationController variables and routes:

class Station::ApplicationController < ApplicationController
end

You might want to read the Rails Guide on Engines for a more detailed explanation on how to make these work together. Ask again if you're still having trouble.

Starknaked answered 10/6, 2012 at 11:13 Comment(2)
Thank your for your reply. Actually, the url helper i'm trying to access is from the module itself. My module is called Station, so I changed my code to call station.pages_url, but i've got this error back : undefined local variable or method station' for Station::Plugins:Class. I also tryied to call my_app.pages_url` since the route i want to call appears in rake routes but i got a similar error : undefined local variable or method main_app' for Station::Plugins:Class`. Do I need to include something in my Module?Extender
Please see the edit in my reply so that you can inherit the routes and variables from the parent application's ApplicationController. Also make sure the top line of your routes.rb file is "AddressBook::Engine.routes.draw do". You should not need to add "Station" in from of your paths from within your engine. You only need to do that when you're trying to access that path from the parent application.Starknaked
W
3

What worked for me was to include the helpers into the specific class:

include ENGINE_NAME::Engine.routes.url_helpers
include Rails.application.routes.url_helpers
Withstand answered 10/8, 2016 at 15:17 Comment(1)
Alternatively, a fallback pattern like Rails.application.routes.url_helpers.try(path_helper_symbol) || ENGINE_NAME::Engine.routes.url_helpers.try(path_helper_symbol) may be less polluting.Kally
M
1

This worked for me, found it while reading ActionPack's code.

Contains all the mounted helpers across different engines and the main_app helper for the application. You can include this in your classes if you want to access routes for other engines.

include ActionDispatch::Routing::RouteSet::MountedHelpers
Marquardt answered 30/7, 2021 at 12:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.