Rails ActiveSupport::Concern 的依赖关系

xiaoronglv · 2013年05月25日 · 最后由 wwwicbd 回复于 2018年08月17日 · 2944 次阅读

今天在学习 codeshool 中的 rails bits 时,被一个细节绕晕了。

百思不得其解,请大家点拨一下。

重构前的代码

module A

  def self.included(base)
    base.extend(B)
  end

  def add_game(game)
  end

  def remove_game(game)
  end

  module B
    def search_by_game_name(name)
    end
  end
end

重构后的代码

module A

  extend ActiveSupport::Concern

  def add_game(game)
  end

  def remove_game(game)
  end

  module B
    def search_by_game_name(name)
    end
  end

end

我的问题是

重构后的代码中,module A 中没有 include B。假如某个 class 使用 module A,Rails 根本不知道顺带要加载 module B 啊。

Rails 是怎么找到 module B 的。

class c
    include A 
end

http://rubybits.codeschool.com/levels/5/challenges/6

ActiveSupport::Concern 只认识 ClassMethods

require 'active_support'

module A
  extend ActiveSupport::Concern

  def add_game(game)
    puts "add_game(#{game})"
  end

  def remove_game(game)
    puts "remove_game(#{game})"
  end

  module ClassMethods
    def search_by_game_name(name)
      puts "search_by_game_name(#{name})"
    end
  end
end

class C
  include A
end

c = C.new

c.add_game(1)
C.search_by_game_name(2)

#1 楼 @fredwu 还有 included block.

module A 
  extend ActiveSupport::Concern

  module ClassMethods
  end

  included do 
  end
end

所以 @xiaoronglv 的问题,Rails 也找不到 B

参考这个 http://ihower.tw/blog/archives/3949 其实看 doc 或者 源码 更靠谱

在 rails5.2 里可以这样写:

# ...
module ClassMethods
  def search_by_game_name(name)
    puts "search_by_game_name(#{name})"
  end
end
# ...

或者

# ...
class_methods do
  def search_by_game_name(name)
    puts "search_by_game_name(#{name})"
  end
end
# ...
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册