代码之家  ›  专栏  ›  技术社区  ›  Dave Smylie

从Rails中的gem重写模块方法

  •  46
  • Dave Smylie  · 技术社区  · 17 年前

    意志宝石在我的先知版本上被打破。默认值 paginate_by_sql willpaginate模块中的方法正在向查询中插入额外的“as”,导致查询失败。

    代码本身是很容易修复的,但我不确定让Rails接受我的更改的最佳方法。

    我不想更改gem本身的代码,因为这会使我的代码在其他机器上被破坏。

    我尝试创建一个lib/test.rb文件,其中包含:

    module WillPaginate
      def paginate_by_sql
        (my code goes here)
      end
    end
    

    需要从environment.rb中获取,但它并没有接受我的更改。 我还尝试从controllers/application.rb中要求它,但还是没有得到我的更改。

    暂时,我让它通过重写特定模型本身中的方法来工作,但是这是一个小技巧,意味着我不能在这个项目中的任何其他模型上使用它。

    我相信有一个简单的方法可以做到这一点,但我没有任何运气用谷歌追踪它。

    3 回复  |  直到 10 年前
        1
  •  29
  •   Sarah Mei    17 年前

    您所做的将有效,但您的代码需要如下所示:

    module WillPaginate
      module Finder
        module ClassMethods
          def paginate_by_sql(sql, options)
            # your code here
          end
        end
      end
    end
    

    换句话说,进入finder.rb,删除除模块头和要重写的方法之外的所有内容,然后保存到lib中的一个文件,并包含在environment.rb中。喂,快来的猴子补丁!

        2
  •  66
  •   Steve Graham    16 年前

    更简洁的解决方案:

    WillPaginate::Finder::ClassMethods.module_eval do
     def paginate_by_sql sql, options
       # Your code here
     end
    end
    

    将代码放入配置/初始值设定项中的初始值设定项文件中。这是放置加载环境时需要运行的代码的正确位置。它还可以更好地组织代码,使每个文件的意图更清晰,从而更容易跟踪错误。不要混乱环境.rb!

        3
  •  48
  •   Abram    10 年前

    好吧,我只想让像我这样的人更容易理解,他们在阅读完其他答案后,仍在挣扎。

    弗斯特 通过搜索代码行,在Github repo上查找要更改的代码(使用 pry )你想改变宝石,然后选择 Code 在左边而不是 Issues

    enter image description here

    enter image description here

    接下来 复制要更改的模块的内容,并将其放入适当命名的 .rb 文件在config/initializers文件夹中。下面是一个例子:

    module Forem
      module TopicsHelper
        def link_to_latest_post(post)
          text = "#{time_ago_in_words(post.created_at)} #{t("ago_by")} #{post.user}"
          link_to text, forum_topic_path(post.topic.forum, post.topic, :anchor => "post-#{post.id}")
        end
      end
    end
    

    现在,将其更改为:

    Forem::TopicsHelper.module_eval do
      def link_to_latest_post(post)
        text = "#{time_ago_in_words(post.created_at)} #{t("ago_by")} #{post.user}"
        link_to text, forum_topic_path(post.topic.forum, post.topic, :anchor => "post-#{post.id}")
      end
    end
    

    现在,对代码进行任何其他更改并重新启动服务器。

    走开!