应用程序助手方法是不是适用于所有视图?
Posted
技术标签:
【中文标题】应用程序助手方法是不是适用于所有视图?【英文标题】:Are application helper methods available to all views?应用程序助手方法是否适用于所有视图? 【发布时间】:2014-09-18 00:53:26 【问题描述】:Rails 4.1
Ruby 2.0
Windows 8.1
在我的 helpers/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'
如果我将 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
【问题讨论】:
你不必在你的控制器中include ApplicationHelper
是的,但这并不能解释我要问的问题
【参考方案1】:
Rails 5 更新。我遇到了一个类似的问题,视图没有从 application_helper.rb 中获取方法。 This post 帮助了我。新 Rails 应用程序的 helpers 目录中提供的文件仅适用于这些视图。 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) %>
。
【讨论】:
【参考方案2】:帮助者
最重要的答案是application_helper
是在您的所有视图中都可用。
Rails 实际上在所有地方都使用了助手 - 从 form_for
到其他内置的 Rails 方法。
由于 Rails 基本上只是一系列类和模块,helpers
在您的视图呈现时被加载,允许您在需要时调用它们。 Controllers
在堆栈中处理得更早,因此您必须在其中明确包含您需要的帮助器
重要提示 - 您无需在 ApplicationController
中包含 ApplicationHelper
。它应该正常工作
您的问题
可能有几种可能性导致问题;我有两个想法给你:
您的
AgentsController
是否继承自ApplicationController
? 也许您包含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
【讨论】:
在控制器中包含 application_helper 是一个 Hail Mary。最初并不知道 application_helper 方法对所有视图都是自动可用的。我会检查其他可能不寻常的地方。感谢您提供的简化方法。 谁投了反对票,请让我知道答案有什么问题。我保持不变,因为我相信它是正确的。 不知道为什么这会被否决,但是当有人在没有发表评论的情况下对答案或问题投反对票时,我觉得这很烦人。我认为这应该是此类论坛的要求。我接受你的回答,对模型方法进行了一点修改 谢谢 - 我不介意投反对票;我只是想知道如何改进,以便下次做得更好以上是关于应用程序助手方法是不是适用于所有视图?的主要内容,如果未能解决你的问题,请参考以下文章
Swiftui Scrollview Viewmodifier 适用于所有 Scrollview
所有以前的移动视图在适用于操作系统版本高于 4.1.x 的三星设备的 Worklight Android 应用程序中可见
iOS - TapGestureRecognizer - 点击适用于整个屏幕而不是视图