Доступны ли вспомогательные методы приложения для всех представлений?

Rails 4.1
Ruby 2.0
Windows 8.1

В моих помощниках/application_helper.rb у меня есть:

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

В моих представлениях/агентах/form.html.erb у меня есть следующее:

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

В моих контроллерах/agents_controller.rb у меня есть следующее:

include ApplicationHelper

Но когда я перехожу к этому представлению, я получаю следующее сообщение об ошибке:

неопределенная локальная переменная или метод `agents_and_ids_generator' для #‹#:0x00000006fc9148>

Если я перенесу метод agent_and_ids_generator в helpers/agents_helper.rb, он будет работать нормально.

Я думал, что если поместить методы в помощник приложения и включить приложение в контроллер, то эти методы станут доступны для представлений. Я не прав в этом предположении?

Отвечать:

Убедившись, что помощник приложения не включен в контроллеры, и добавил следующее упрощение:

<%= 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

person EastsideDev    schedule 26.07.2014    source источник
comment
вам не нужно include ApplicationHelper в вашем контроллере   -  person Rajarshi Das    schedule 26.07.2014
comment
да, но это не объясняет проблему, о которой я спрашиваю   -  person EastsideDev    schedule 26.07.2014


Ответы (2)


Помощники

Суть в том, что application_helper есть во всех ваших представлениях.

На самом деле Rails использует хелперы повсюду — от подобных form_for до других встроенных методов Rails.

Поскольку Rails — это, по сути, просто набор классов и модулей, helpers загружаются при рендеринге ваших представлений, что позволяет вам вызывать их всякий раз, когда вам нужно. Controllers обрабатываются намного раньше в стеке, и поэтому вы должны явно включать в них нужные вам хелперы

Важно: вам не нужно включать ApplicationHelper в ApplicationController. Это должно просто работать


Ваша проблема

Проблема может быть вызвана несколькими причинами; У меня есть две идеи для вас:

  1. Ваш AgentsController наследуется от ApplicationController?
  2. Возможно, ваше включение ApplicationHelper вызывает проблему

Странно, что у вас AgentsHelper работает, а ApplicationHelper нет. Одним из способов объяснить это может быть то, что Rails будет загружать помощника в зависимости от используемого контроллера, то есть, если вы не наследуете от ApplicationController,, ApplicationHelper не будет вызываться.

Вам нужно будет протестировать это:

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

Затем вам нужно избавиться от include ApplicationHelper в вашем контроллере. Это делает помощника доступным только для этого класса (контроллера) и не будет иметь никакого отношения к вашему представлению.

Сказав это, это может вызвать проблему с вашим представлением, загружающим ApplicationHelper, а это означает, что вам обязательно нужно попробовать удалить его из вашего ApplicationController


Метод

Наконец, ваш метод можно значительно упростить, используя 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
person Richard Peck    schedule 26.07.2014
comment
в том числе application_helper в контроллере было радуйся, Мария. Этого не было изначально, зная, что методы application_helper автоматически доступны для всех представлений. Я проверю на предмет чего-нибудь еще, что может быть необычным. Спасибо за упрощенный метод. - person EastsideDev; 26.07.2014
comment
Кто бы ни проголосовал, пожалуйста, дайте мне знать, что не так с ответом. Я оставляю его без изменений по той простой причине, что считаю его правильным. - person Richard Peck; 26.07.2014
comment
Не знаю, почему за это проголосовали, но меня очень раздражает, когда кто-то голосует против ответа или вопроса, не оставляя комментария. Я думаю, что это должно быть требованием для такого типа форума. Я принимаю ваш ответ с одной незначительной модификацией метода модели. - person EastsideDev; 28.07.2014
comment
Спасибо - я не против отрицательных голосов; Я просто хочу знать, как я могу улучшить, чтобы сделать его лучше в следующий раз - person Richard Peck; 28.07.2014

Обновление Рельс 5. Я столкнулся с аналогичной проблемой, когда представления не подбирали метод из application_helper.rb. Это сообщение помогло мне. Файлы, находящиеся в каталоге helpers нового приложения rails, предназначены только для этих представлений. Методы в application_helper.rb не будут автоматически доступны для всех представлений. Чтобы создать вспомогательный метод, доступный для всех представлений, создайте новый вспомогательный файл в вспомогательном каталоге, таком как clean_emails_helper.rb, и добавьте сюда свой собственный метод, например:

Module CleanEmailsHelper
  def clean_email(email)
     *do some stuff to email*
     return email
  end
end

Затем вы можете вызвать <%= clean_email(email) %> из любого представления вашего приложения.

person tomb    schedule 20.05.2019