Rails 重写 Gem 的某些 helper 方法问题

adventurelw · 2013年01月30日 · 最后由 littleluren 回复于 2013年02月03日 · 3731 次阅读

rails_admin gem 的 app/helper/rails_admin/application_helper.rb 里 edit_user_link 方法需要重写一下,但在自己的 app/helper/rails_admin/application_helper.rb 没有办法只写这一个,全都要拷过来才行。 请教有没有办法只写 edit_user_link 这一个方法的?因为其余不需要改变。 万分感谢。

你干嘛重写人家方法呢 在很多情况下都不是一个很好的选择 人家的方法说不定也会自己改写,到时候和你的弄不到一起就麻烦了,这种问题很难查出来了。 不过 Ruby hack 方法一般很容易,把原方法和你想 hack 的方案贴出来吧

不是说原方法不好,不过原方法显示 email,我改成了 login

def edit_user_link
  return nil unless authorized?(:edit, _current_user.class, _current_user) && _current_user.respond_to?(:email)
  return nil unless abstract_model = RailsAdmin.config(_current_user.class).abstract_model
  return nil unless edit_action = RailsAdmin::Config::Actions.find(:edit, {:controller => self.controller, :abstract_model => abstract_model, :object => _current_user })
  link_to _current_user.email, url_for(:action => edit_action.action_name, :model_name => abstract_model.to_param, :id => _current_user.id, :controller => 'rails_admin/main')
end

只改了最后一行,link_to _current_user.email 的 email 改成 login...

不知道 Markdown 多行代码怎么排版,网上说制表符或者四个空格,怎么都无效。。。。。。

#3 楼 @adventurelw 看编辑框后面有说明呀

#4 楼 @huacnlee 只有单行代码的说明,结果还是排不好版。。。。。

#5 楼 @adventurelw 你就没仔细看,后面还有提到按 M 键看更多啊

在 config/initialize 里面加个文件 内容为

require 'rails_admin/i18n_support' module RailsAdmin module ApplicationHelper include RailsAdmin::I18nSupport def edit_user_link #coding end end end

#6 楼 @huacnlee 哦,看到了,昨天按了半天 M 键没出来那个窗口。。。。。

#7 楼 @littleluren 呃,试了一下,虽然没有错误发生,但也没有效果,读取的只是 gem 自有的方法。。。。。。再次求教!!!!!!!

10 楼 已删除

好像改 engine 的 helper 方法有 bug,参考地址:https://github.com/rails/rails/issues/6496

不过好像也有人解决了 http://stackoverflow.com/questions/9232175/access-main-app-helpers-when-overridings-a-rails-engine-view-layout

大概流程就是把方法写在 main_app 的 helper 里面,然后将路径加到 engine 的 helper path 的数组上

Engines are supposed to be independent from the main app, that is why you can't access its helpers from the Engine.

However, there are hack-ish ways for giving your engine access to the helpers of the main app. This is how I did it:

# In the main app # initializers/share_helpers_path_with_engine.rb PhotoGallery::Engine.class_eval do paths["app/helpers"] << File.join(File.dirname(FILE), '../..', 'app/helpers') end

You need of course to change PhotoGallery to the actual name of your engine class.

Feel free to take a look at the Engines documentation (section about the paths):
http://edgeapi.rubyonrails.org/classes/Rails/Engine.html

以上是别人答案。 你把 helper 方法写在项目的 application_helper.rb 里面,参照上面写个文件将 PhotoGallery::Engine 改为 RailsAdmin::Engine 应该就好了

#11 楼 @littleluren 居然还是没搞定。。。。 不知道是不是因为 RailsAdmin::Engine 里面有 isolate_namespace RailsAdmin 的原因,依然无效,但也没有错误发生。

我试了一下果然没有成功. 那就这样吧,在 config/initialize 新建一个 rb 文件,内容如下:

RailsAdmin::ApplicationController.class_eval do def edit_user_link #coding end helper_method :edit_user_link end

我用本地的一个 engine 测试过,成功覆盖了 engine 原有的 helper 方法。

#13 楼 @littleluren 居然成了,不过由于 rails_admin 在 MainController 里面包含了 ApplicationHelper,所以要改成 RailsAdmin::MainController.class_eval do 才能保证覆盖原方法。 并且由于这是在 Controller 环境中定义,第三行的 edit_action = RailsAdmin::Config::Actions.find(:edit, {:controller => self.controller,..... 要改成 edit_action = RailsAdmin::Config::Actions.find(:edit, {:controller => self,..... 否则会出现找不到 controller 方法的错误 最后一行的 link_to 方法需要加 ApplicationController.helpers 前缀,应该也是因为在 controller 中定义。 十分感谢。

成了就好,rails_admin 具体的代码我没仔细看

需要 登录 后方可回复, 如果你还没有账号请 注册新账号