3

Story mode

Just started learning RoR, but in short period of time I need to add functionality similar to Loading images from LDAP (incompatible version) into our project. Project is abondoned, and I can't find any related info/docs, so I'm asking for help here. Solution, tutorial, anything could work.

Error log

$ ruby bin/rake redmine:plugins RAILS_ENV="production"
rake aborted!
NoMethodError: undefined method `alias_method_chain' for ApplicationHelper:Module
Did you mean?  alias_method
...

Monkey patch that needs update

plugins\redmine_gemavatar\lib\application_helper_gemavatar_patch.rb :

require 'application_helper'

module GemAvatarPlugin
    module ApplicationAvatarPatch
        def self.included(base)
            base.send(:include, InstanceMethods)
            base.class_eval do
                alias_method_chain :avatar, :gemavatar
            end
        end
        module InstanceMethods
            def avatar_with_gemavatar(user, options = { })
                if Setting.gravatar_enabled? && user.is_a?(User)
                    options.merge!({:ssl => (defined?(request) && request.ssl?), :default => Setting.gravatar_default})
                    options[:size] = "64" unless options[:size]
                    avatar_url = url_for :controller => :pictures, :action => :delete, :user_id => user
                    return "<img class=\"gravatar\" width=\"#{options[:size]}\" height=\"#{options[:size]}\" src=\"#{avatar_url}\" />".html_safe
                else
                    ''
                end
            end
        end
    end
end

My attempts / Articles

I've found good article here How To Replace alias_method_chain, but I'm not quite sure how to apply prepend style to redmine plugin's monkey patch. Just can't get it work :/

Norman Edance
  • 352
  • 4
  • 14
  • Found another article [Module.prepend: a super story](https://hashrocket.com/blog/posts/module-prepend-a-super-story) which might be helpful for someone. – Norman Edance Apr 26 '19 at 12:31

3 Answers3

2

Is this related to this plugin?

If so, here is how I would do it:

  • In the init.rb file, change this:
RedmineApp::Application.config.after_initialize do
  ApplicationHelper.send(:include, GemAvatarPlugin::ApplicationAvatarPatch)
end

To this:

RedmineApp::Application.config.after_initialize do
  ApplicationHelper.prepend(GemAvatarPlugin::ApplicationAvatarPatch)
end
  • In lib/application_helper_gemavatar_patch.rb, change this:
require 'application_helper'

module GemAvatarPlugin
  module ApplicationAvatarPatch

    def self.included(base)
      base.send(:include, InstanceMethods)
      base.class_eval do
        alias_method_chain :avatar, :gemavatar
      end
    end

    module InstanceMethods

      def avatar_with_gemavatar(user, options = { })
        # method content omitted for clarity
      end

    end
  end
end

to this:

module GemAvatarPlugin
  module ApplicationAvatarPatch

    def avatar(user, options = { })
      # method content omitted for clarity
    end

  end
end

I would remove the require 'application_helper' because I don't see why it's needed

ste26054
  • 419
  • 3
  • 11
  • For some reasons it's not working. Loads only gravatar_default image. Seems like it never enters Picture model and asks for pictures as `/people/avatar?id=1005` while it's should be smth like `/gemavatar/1005` – Norman Edance May 03 '19 at 08:16
  • Hmm that is weird, it is working fine for me... Do you have another plugin installed, like `redmine_people`? – ste26054 May 03 '19 at 09:00
  • Also, what do you get if you launch a `rails c` from the `redmine` directory and run a `ApplicationHelper.included_modules`? – ste26054 May 03 '19 at 09:14
  • Yeah, Im using people. Heres included_modules: `[GemAvatarPlugin::ApplicationAvatarPatch, RedminePeople::Patches::ApplicationHelperPatch::InstanceMethods, RedminePeople::Patches::ApplicationHelperPatch, Redmine::Helpers::URL, Redmine::Hook::Helper, Redmine::Themes::Helper, Redmine::SudoMode::Helper, Redmine::Paginatio n::Helper, GravatarHelper::PublicMethods, Redmine::I18n, Redmine::WikiFormatting::Macros::Definitions]` – Norman Edance May 03 '19 at 09:24
  • Ok, I've disabled `redmine_people` by prepending .. to it's folder name :D. It's still not doing stuff. – Norman Edance May 03 '19 at 09:30
  • Thanks to the prepend, the GemAvatarPlugin patch is loaded first so it should work properly. When you go to `/my/account`, do you get something like this in the rails log: `Started GET "/gemavatar/:user_id"`? – ste26054 May 03 '19 at 09:30
  • Nah, it's getting `"GET /people/avatar?id=1005&size=50x50 HTTP/1.1" 404 11160 http://localhost:3000/my/account -> /people/avatar?id=1005&size=50x50` – Norman Edance May 03 '19 at 09:41
  • Might be relevant: in logs `Missing template, responding with 404: Missing template people/avatar, application/avatar with {:locale=>[:ru, :en], :formats=>[:html], : variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :axlsx, :rsb]}.` – Norman Edance May 03 '19 at 09:45
  • In Redmine settings/display, did you enable `Use Gravatar user icons`? (It seems to be required by the plugin) – ste26054 May 03 '19 at 09:49
  • Yes I did. And it shows only default gravatar images (same behavior as without plugin) – Norman Edance May 03 '19 at 10:10
1

I also tried to update this plugin. I used https://github.com/alexandermeindl/redmine_local_avatars as an example.

In init.rb changed this:

RedmineApp::Application.config.after_initialize do
  ApplicationHelper.send(:include, GemAvatarPlugin::ApplicationAvatarPatch)
end

to this:

RedmineApp::Application.config.after_initialize do    
  ApplicationHelper.include ApplicationAvatarPatch
end

the patched lib/application_helper_gemavatar_patch.rb, looks like this:

module ApplicationAvatarPatch    
def self.included(base)
    base.send(:include, InstanceMethods)

    base.class_eval do
        alias_method :avatar_without_gemavatar, :avatar
        alias_method :avatar, :avatar_with_gemavatar
    end
end

module InstanceMethods
    def avatar_with_gemavatar(user, options = { })
        if Setting.gravatar_enabled? && user.is_a?(User)
            options.merge!({:ssl => (defined?(request) && request.ssl?), :default => Setting.gravatar_default})
            options[:size] = "64" unless options[:size]
            avatar_url = url_for :controller => :pictures, :action => :delete, :user_id => user
            return "<img class=\"gravatar\" width=\"#{options[:size]}\" height=\"#{options[:size]}\" src=\"#{avatar_url}\" alt=\"Gemavatar text\" />".html_safe
        else
            avatar_without_gemavatar(user, options)
        end
    end
end
end

I tried it only with Redmine 4.0.3 but it seems to be working. However there are warnings in the webserver log:

127.0.0.1 - - [06/Mar/2020:20:58:23 CET] "GET /gemavatar/164 HTTP/1.1" 200 3545
http://tredmine1:3000/users/164 -> /gemavatar/164
[2020-03-06 20:58:23] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

In the redmine_local_avatars plugin there was a different patch for Redmine 4.1.

Update: I set a up a github repository with the changes: https://github.com/pentekl/redmine_gemavatar

nemBela
  • 11
  • 3
0

You can use alias_method instead of alias_method_chain, but I'm searching for something like prepend solution

                alias_method :avatar_without_gemavatar, :avatar
                alias_method :avatar, :avatar_with_gemavatar

UPD: But it throws warnings:

/app/helpers/application_helper.rb:180: warning: already initialized constant ApplicationHelper
::RECORD_LINK
/app/helpers/application_helper.rb:180: warning: previous definition of RECORD_LINK was here
/app/helpers/application_helper.rb:199: warning: already initialized constant ApplicationHelper
::ATTACHMENT_CONTAINER_LINK
/app/helpers/application_helper.rb:199: warning: previous definition of ATTACHMENT_CONTAINER_LI
NK was here
/app/helpers/application_helper.rb:1053: warning: already initialized constant ApplicationHelpe
r::LINKS_RE
/app/helpers/application_helper.rb:1053: warning: previous definition of LINKS_RE was here
Exiting

UPD: As ste26054 mentioned in his answer and commented here require 'application_helper' can be deleted to prevent warnings, since it already included in the core.

Norman Edance
  • 352
  • 4
  • 14
  • You can not `require 'application_helper'`. It is required at runtime and you can find it in your `/app` rails app folder. You are probably trying to require the wrong file. You can display the autoloads path by running `echo $LOAD_PATH` in your terminal and get more info about the [method `require` of `Kernel` module here](http://ruby-doc.org/core-2.6.3/Kernel.html#method-i-require). Please share the `repository` of your project on `github` and the url for `plugins\redmine_gemavatar\lib\application_helper_gemavatar_patch.rb` so that I can post my solution to this problem. – Fabrizio Bertoglio Apr 30 '19 at 09:04