ruby-on-railsruby-on-rails-6ruby-on-rails-5.2ruby-on-rails-6.1zeitwerk

How to access ApplicationHelper methods in namespaced views?


I have a module ApplicationHelper in app/helpers/application_helper.rb defined like this

module ApplicationHelper
  def some_method(arg)
    
  end
end

and i have my view file is here

app/views/v1/admin/messages/show.json.jbuilder

So i am trying to access the

some_method()

in view file but it doesn't reflect! Is this due to namespacing? or what i am not able to understand. It would be Great if someone explains the concept. Thanks in advance!

it says undefined method error what could be the reason?


Solution

  • You didn't include your controller code, but we'll assume it ultimately inherits from ActionController::API (as it should it if it is an API controller). If so, that is the root of it rather than namespacing, etc. Per the ActionController documentation:

    An API Controller is different from a normal controller in the sense that by default it doesn't include a number of features that are usually required by browser access only: layouts and templates rendering, flash, assets, and so on. This makes the entire controller stack thinner, suitable for API applications. It doesn't mean you won't have such features if you need them: they're all available for you to include in your application, they're just not part of the default API controller stack.

    One of the side effects of the thinner API controller is that they don't automatically include helpers like a standard Rails controller. You can easily add that back in, though.

    messages_controller.rb

    class Api::V1::MessagesController < ActionController::API
      include ActionController::Helpers 
      helper ApplicationHelper
      
      def show
        # whatever
      end
    end
    

    app/helpers/application_helper.rb

    module MessagesHelper
      def some_method(arg)
        # whatever
      end
    end
    

    app/views/messages/show.json.jbuilder

    json.bogus do
      thing1: some_method('banana')
    end
    

    If you have lots of API controllers, you can of course stick it in a base controller class they all inherit from like so:

    class Api::V1::ApiController < ActionController::API
      include ActionController::Helpers
      helper ApplicationHelper
    end