我对那个 Rails 中的 helper 有点困惑,为什么我的 Helper 里面的方法对所有的 view 是可见的? 比如我在 pages_helper.rb 中定义了一个 def testhelper end 那个这个 testhelper 不仅对 view 中的 pages 可见,对 view 中的 user 也是可见的?这样的话作用域不是太大了?谢谢!
我看 CodeSchool 里面关于 Helper 这样说 Issues with Rails view helpers
举个例子 app/helpers/posts_helper.rb
module PostsHelper
def publication_date(post)
post.created_at.strftime '%Y-%m-%d'
end
end
app/views/posts/show.html.erb
<span><%= publication_date @post %></span>
上面的都是没问题的,但是如果下面这样
<span><%= publication_date @user %></span>
上面的代码是允许的,但是显然是错误的
他们的建议是使用 Decorators 来处理这些视图中的输出,楼主可以查查,我觉得挺麻烦的。
#2 楼 @teddy_1004 谢谢您的回答,但是我的困惑是 Helpers 对于所有的 View 是可见的,这样作用域会不会太大了,容易有冲突,比如说我在 PagesHelper 和 UsersHelper 中有两个相同名字的 method,这样的话 views 中看到的 method 到底是哪个?
module PagesHelper
def testpage
"testpagehelper"
end
end
module UsersHelper
def testpage
"testuserhelper"
end
end
现在我很少用具体到 controller 的 helpers,不过记得在 Rails3 里面是不行的。PageHelpers 只能作用到 views/pages,这也符合 Rails 的统一命名。楼主你确定是真的全部可见?
我认为这也是一个约定吧
首先,每个 view
都有自己对应的 helper
模块,如果遵守这样的约定,那么 view 使用的 helper 方法就在对应的 helper 模块中查找,这样看起来也比较整洁。
其次,如果 view1 需要使用 view2 中的 helper 方法,那么我也可以直接调用,这样我就可以不用再 view1 的 helper 模块中再次重写此方法了,这样也避免了代码的重复。
找到答案了,确实后来默认是全部包括了,就像楼主和 Rei 所说的情况。
By default, each controller will include all helpers. These helpers are only accessible on the controller through .helpers
但是,如果确实想要一一对应,也可以更改 Rails 设置
In previous versions of Rails the controller will include a helper whose name matches that of the controller, e.g., MyController will automatically include MyHelper. To return old behavior set config.action_controller.include_all_helpers to false.
http://api.rubyonrails.org/classes/ActionController/Helpers.html
@zgm 查个文档而已,谈不上厉害 :) 我也觉得在尽量少用的前提下,helper 放在全局在一些时候还是有意义的,但分开 controller 实在没有必要,容易造成重名污染,就像楼主所说的不知道哪个起了作用。这个改动还是挺好的,强迫所有的 helper 放在同一地方减少污染机会。
个人也感觉使用 view helper 范围太大了,而且在使用过程中,会发现有时候看到一个 helper 方法,但是一下子找不到对应的文件。后来用 draper
这个 gem,用 decorator 取代原来的 helper 方法,这样作用范围就小很多,而且找对应文件的时候也能方便些。感觉比较好的一个 gem