Overriding a module method from a gem in Rails

前端 未结 3 571
不知归路
不知归路 2020-11-29 21:23

The will_paginate gem is broken on my version of Oracle. The default paginate_by_sql method in the WillPaginate module is inserting an extra \'AS\' into a query

相关标签:
3条回答
  • 2020-11-29 21:26

    What you are doing will work, but your code needs to look like this:

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

    In other words, go into finder.rb, delete everything except the module headers and the method you want to override, then save to a file in lib and include in environment.rb. Voila, instant monkey patch!

    0 讨论(0)
  • 2020-11-29 21:28

    Ok, I'm just going to make this easier for people like myself who come along and still struggle a bit after reading the other answers.

    First find the code that you want to change on the github repo by searching for the line of code (you could easily find this using pry) you want to change in the gem, and then selecting Code on the left instead of Issues

    enter image description here

    enter image description here

    Next Copy the content of the module you want to change and place it into an aptly named .rb file inside of your config/initializers folder. Here is an example:

    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
    

    Now, change it to:

    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
    

    Now, make any additional changes to the code and restart your server.

    Away you go!

    0 讨论(0)
  • 2020-11-29 21:51

    A more concise solution:

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

    Put the the code into an initializer file in config/initializers. This is the correct place to put code that needs to be run when the environment is loaded. It also better organises your code, making each file's intent clearer, thus bugs will be easier to track down. Do not clutter up environment.rb!

    0 讨论(0)
提交回复
热议问题