从ActiveRecord回调到外部模块

时间:2017-07-26 20:41:00

标签: ruby-on-rails ruby activerecord

我有两个类,都使用OAuth 2 Bearer Access令牌对同一服务器进行API调用。我正在尝试将API相关代码包装在一个模块中,以便我可以轻松地从这两个类中利用ActiveRecord的回调功能。 我找不到任何描述如何访问调用类数据的地方(或者如果我必须将它作为带回调的参数传递)。

module M
  BASE_URL = 'www.googleapis.com'
  TOKEN = *generated oauth token*
  module N
    def my_method
      print("id: #{C.id}")
      print("fname: #{C.f_name}")
      print("lname: #{C.l_name}")
      print("address: #{C.address}")
    end
  end
  module O
    def my_method
      #assume this does something different from module N
      print("id: #{D.id}")
      print("fname: #{D.f_name}")
      print("lname: #{D.l_name}")
      print("address: #{D.address}")
    end
  end
end

class C
    include M
    attr_accessible :id, :f_name, :l_name, :address
    after_create N::my_method
end
class D
  include M
  attr_accessible :id, :f_name, :l_name, :address
  after_create O::my_method
end

如何从模块M的my_method中访问C类数据?还是我完全偏离基地?

2 个答案:

答案 0 :(得分:0)

当你像这样包含它时,self中的my_method将是C的一个实例。所以你只需要正常访问这些属性,就好像它是C本身的方法一样。

module M
  def my_method
    print("id: #{id}")
    print("fname: #{f_name}")
    print("lname: #{l_name}")
    print("address: #{address}")
  end
end

理解“当前self”的概念以及不同的结构(包括模块,instance_eval等)如何影响它,对于成为红宝石中的任何优点至关重要。

答案 1 :(得分:0)

ModuleA中加入ClassB会为所有ClassB的实例方法提供ModuleA,就好像它们已直接在ClassB中定义一样。这些方法与ClassB的其他实例方法没有什么不同。您以相同的方式调用它们(b = ClassB.new; b.a_method),并且方法self中将是调用该方法的ClassB实例,因此您可以直接访问定义的任何其他方法或变量在ClassB实例范围内。

如果您有嵌套模块,则可以将其包含在其父模块中,然后包含父模块的任何类都可以访问嵌套模块的方法。

module A
  module B
    def where_am_i
      "Inside mod B"
    end
  end

  include B
end

class C
  include A
end

c = C.new
c.where_am_i # => "Inside mod B"

在您的情况下,两个嵌套的模块应该具有相同方法名称的不同定义,因此您只想包含一个或另一个。您可以使用语法include ParentModule::NestedModule

执行此操作
module M
  BASE_URL = 'www.googleapis.com'
  TOKEN = *generated oauth token*

  module N
    def my_method
      print("id: #{id}")
      print("fname: #{f_name}")
      print("lname: #{l_name}")
      print("address: #{address}")
    end
  end

  module O
    def my_method
      #assume this does something different from module N
      print("id: #{id}")
      print("fname: #{f_name}")
      print("lname: #{l_name}")
      print("address: #{address}")
    end
  end
end

class C
  include M::N
  attr_accessible :id, :f_name, :l_name, :address
  after_create :my_method
end

class D
  include M::O
  attr_accessible :id, :f_name, :l_name, :address
  after_create :my_method
end