ruby-on-railsruby-on-rails-4.1

Are application helper methods available to all views?


Rails 4.1
Ruby 2.0
Windows 8.1

In my helpers/application_helper.rb, I have:

def agents_and_ids_generator
    agents = Agent.all.order(:last)
    if agents
      agents_and_ids = [['','']]
      agents.each do |l|
        name = "#{l.first} #{l.last}"
        agents_and_ids << [name,l.id]
      end
      return agents_and_ids
    end
  end

In my views/agents/form.html.erb, I have the following:

<%= f.select :agent_id, options_for_select(agents_and_ids_generator) %>

In my controllers/agents_controller.rb, I have the following:

include ApplicationHelper

But when I go to this view, I get the following error message:

undefined local variable or method `agents_and_ids_generator' for #<#:0x00000006fc9148>

If I move the agents_and_ids_generator method to the helpers/agents_helper.rb, it works fine.

I thought that by putting methods in the application helper and including the application in a controller, then these methods are available to the views. Am I incorrect in that assumption?

Answer:

Making sure that application helper is not included in controllers, and added the following simplification:

<%= f.collection_select :agent_id, Agent.all.order(:last), :id, :name_with_initial, prompt: true %>

#app/models/agent.rb
Class Agent < ActiveRecord::Base
   def name_with_initial
     "#{self.first} #{self.last}"
   end
end

Solution

  • Helpers

    The bottom line answer is the application_helper is available in all your views.

    Rails actually uses helpers all over the place - in everything from the likes of form_for to other built-in Rails methods.

    As Rails is basically just a series of classes & modules, the helpers are loaded when your views are rendered, allowing you to call them whenever you need. Controllers are processed much earlier in the stack, and thus you have to explicitly include the helpers you need in them

    Important - you don't need to include the ApplicationHelper in your ApplicationController. It should just work


    Your Issue

    There may be several potentialities causing the problem; I have two ideas for you:

    1. Is your AgentsController inheriting from ApplicationController?
    2. Perhaps your inclusion of ApplicationHelper is causing an issue

    Its strange that your AgentsHelper works, and ApplicationHelper does not. One way to explain this would be that Rails will load a helper depending on the controller which is being operated, meaning if you don't inherit from ApplicationController, the ApplicationHelper won't be called.

    You'll need to test with this:

    #app/controllers/application_controller.rb
    Class AgentsController < ApplicationController
       ...
    end
    

    Next, you need to get rid of the include ApplicationHelper in your controller. This only makes the helper available for that class (the controller), and will not have any bearing on your view

    Having said this, it may be causing a problem with your view loading the ApplicationHelper - meaning you should definitely test removing it from your ApplicationController


    Method

    Finally, your method could be simplified massively, using collection_select:

    <%= f.collection_select :agent_id, Agent.all.order(:last), :id, :name_with_initial, prompt: true %>
    
    #app/models/agent.rb
    Class Agent < ActiveRecord::Base
       def name_with_initial
           "#{l.first} #{l.last}"
       end
    end