简体   繁体   中英

Ruby - How to access module's methods?

I'm installing a forum using the Forem gem. There's an option that allows avatar personalization, since it's possible to login with Facebook. You just specify your method in the User model and that's it.

# Forem initializer
Forem.avatar_user_method = 'forem_avatar'

# User model
def forem_avatar
  unless self.user_pic.empty?
    self.user_pic
  end
end

But I want a fallback on Gravatar for normal, non-facebook accounts. I've found the method on Forem and in theory, I need to call the avatar_url method:

# User model
def forem_avatar
  unless self.user_pic.empty?
    self.user_pic
  else
    Forem::PostsHelper.avatar_url self.email
  end
end

However, Forem isn't an instance, but a module and I can't call it nor create a new instance. The easy way is to copy the lines of that method, but that's not the point. Is there a way to do it?

Thanks

Update

Both answers are correct, but when I call the method either way, there's this undefined local variable or method 'request' error, which is the last line of the original avatar_url .

Is there a way to globalize that object like in PHP? Do I have to manually pass it that argument?

perhaps reopen the module like this:

module Forem
  module PostsHelper
    module_function :avatar_url
  end
end

then call Forem::PostsHelper.avatar_url

if avatar_url call other module methods, you'll have to "open" them too via module_function

or just include Forem::PostsHelper in your class and use avatar_url directly, without Forem::PostsHelper namespace

If you want to be able to use those methods in the user class, include them and use

class User < ActiveRecord::Base
  include Forem::PostsHelper

  def forem_avatar
    return user_pic if user_pic.present?
    avatar_url email
  end
end

Another way would be to set the Forem.avatar_user_method dynamically since the Forem code checks it it exists before using it and defaults to avatar_url if it does not.

class User < ActiveRecord::Base

  # This is run after both User.find and User.new
  after_initialize :set_avatar_user_method

  # Only set avatar_user_method when pic is present
  def set_avatar_user_method
    unless self.user_pic.empty?
      Forem.avatar_user_method = 'forem_avatar'
    end
  end

  def forem_avatar
    self.user_pic
  end
end

This way you dont pollute your model with unnecessary methods from Forem and don't monkey patch Forem itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM