55

will_paginate gem 在我的 Oracle 版本上已损坏。WillPaginate 模块中的默认paginate_by_sql方法是在查询中插入额外的“AS”并导致查询失败。

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

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

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

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

并从 environment.rb 中要求它,但它没有接受我的更改。我也尝试从 controllers/application.rb 中要求它,但同样,没有接受我的更改。

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

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

4

3 回答 3

78

更简洁的解决方案:

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

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

于 2009-12-05T15:14:36.830 回答
60

好的,我只是想让像我这样的人在阅读其他答案后仍然有些挣扎。

首先通过在 gem 中搜索要更改的代码行(您可以使用pry轻松找到)在 github repo 上找到要更改的代码,然后Code在左侧选择而不是Issues

在此处输入图像描述

在此处输入图像描述

接下来复制您要更改的模块的内容并将其放入.rbconfig/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

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

你走开!

于 2014-01-30T01:10:41.250 回答
32

你正在做的将工作,但你的代码需要看起来像这样:

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

换句话说,进入 finder.rb,删除除模块头和要覆盖的方法之外的所有内容,然后保存到 lib 中的文件并包含在 environment.rb 中。瞧,即时猴子补丁!

于 2009-02-24T04:44:56.407 回答