创建动态方法名称Ruby on Rails

时间:2014-07-16 21:32:49

标签: ruby-on-rails ruby devise

设计源代码显示映射:

def self.define_helpers(mapping) #:nodoc:
  mapping = mapping.name

  class_eval <<-METHODS, __FILE__, __LINE__ + 1
    def authenticate_#{mapping}!(opts={})
      opts[:scope] = :#{mapping}
      warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
    end

    def #{mapping}_signed_in?
      !!current_#{mapping}
    end

    def current_#{mapping}
      @current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
    end

    def #{mapping}_session
      current_#{mapping} && warden.session(:#{mapping})
    end
  METHODS

  ActiveSupport.on_load(:action_controller) do
    helper_method "current_#{mapping}", "#{mapping}_signed_in?", "#{mapping}_session"
  end
end

允许创建方法current_useruser_signed_in?和其他方法。

我想学习如何为像

这样的方法创建自己的动态命名

当我尝试用它来模拟它时:

class Devise
    mapping = "user"
    def self.current_#{mapping}
        puts "hello"
    end
    def self.puts_current
        puts @current_#{user}
    end
end

Devise.current_user

我收到错误:undefined method 'current_user' for Devise:Class (NoMethodError)

2 个答案:

答案 0 :(得分:2)

您错过了Devise正在使用的class_eval电话。这使他们能够使用字符串插值来动态创建方法。

试试这个:

class Devise

  mapping = "user"

  class_eval <<-METHOD
    def self.current_#{mapping}
      puts "hello"
    end
  METHOD

end

Devise.current_user

答案 1 :(得分:1)

请注意,您尝试使用的行位于&quot; class_eval&#39;块。你可以试试

class Devise
    mapping = "user"

    class_eval <<-METHODS

    def self.current_#{mapping}
        puts "hello"
    end
    def self.puts_current
        puts @current_#{mapping}
    end

    METHODS
end

Devise.current_user

......这会奏效。或者阅读一些关于 class_eval 的文档以供理解。