Переопределение метода модуля из гема в Rails - PullRequest
46 голосов
/ 24 февраля 2009

Драгоценный камень will_paginate не работает в моей версии Oracle. Метод paginate_by_sql по умолчанию в модуле WillPaginate вставляет дополнительный «AS» в запрос и вызывает его сбой.

Сам код легко исправить, но я не уверен в том, что Rails сможет лучше принять мои изменения.

Я не хочу менять код в самом геме, так как это приведет к тому, что мой код будет поврежден на других машинах.

Я попытался создать файл lib / test.rb, содержащий:

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

и требует его от environment.rb, но он не принимает мои изменения. Я также попытался запросить его из controllers / application.rb, но опять же не принимал мои изменения.

Временно, я заставил его работать, переопределив метод внутри самой конкретной модели, но это немного хак, и это означает, что я не могу использовать его ни на одной из других моделей в этом проекте.

Я уверен, что есть простой способ сделать это, но мне не повезло, выслеживая его с помощью Google.

Ответы [ 3 ]

67 голосов
/ 05 декабря 2009

Более краткое решение:

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

Поместите код в файл инициализатора в config / initializers. Это правильное место для размещения кода, который должен выполняться при загрузке среды. Это также лучше организует ваш код, делая цель каждого файла более ясной, таким образом, ошибки будут легче отследить. Не загромождайте окружающую среду.rb!

49 голосов
/ 30 января 2014

Хорошо, я просто сделаю это проще для таких людей, как я, которые приходят и все еще немного борются после прочтения других ответов.

Сначала найдите код, который вы хотите изменить в репозитории github, выполнив поиск строки кода (вы можете легко найти это, используя pry ) Вы хотите изменить в драгоценном камне, а затем выбрав Code слева вместо Issues

enter image description here

enter image description here

Далее Скопируйте содержимое модуля, который вы хотите изменить, и поместите его в файл с точно названным .rb в папке config / initializer. Вот пример:

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

Теперь внесите дополнительные изменения в код и перезапустите сервер.

Прочь!

29 голосов
/ 24 февраля 2009

То, что вы делаете, будет работать, но ваш код должен выглядеть так:

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

Другими словами, зайдите в finder.rb, удалите все, кроме заголовков модулей и метода, который вы хотите переопределить, затем сохраните в файл в lib и включите в environment.rb. Вуаля, мгновенный патч обезьяны!

...