Ruby on Rails,包括带参数的模块

在包含ruby模块时有没有办法使用参数? 我有一个模块Assetable,它包含在许多类中。 我希望能够动态生成attr_accessor。

module Assetable extend ActiveSupport::Concern included do (argument).times do |i| attr_accessor "asset_#{i}".to_sym attr_accessible "asset_#{i}".to_sym end end end 

包含模块时无法传递参数。 接下来最好的事情是定义一个类方法,让您在之后创建所需的内容:

 module Assetable extend ActiveSupport::Concern module ClassMethods def total_assets(number) number.times do |i| attr_accessor "asset_#{i}" attr_accessible "asset_#{i}" end end end end class C include Assetable total_assets 3 end o = C.new o.asset_2 = "Some value." o.asset_2 #=> "Some value." 

在覆盖问题时覆盖included方法时也要小心,因为它也被ActiveSupport::Concern 。 您应该在overriden方法中调用super ,以确保正确初始化。

有一个技巧:创建一个inheritance自模块的类,以便您可以将任何参数传递给模块,如类。

 class Assetable < Module def initialize(num) @num = num end def included(base) num = @num base.class_eval do num.times do |i| attr_accessor "asset_#{i}" end end end end class A include Assetable.new(3) end a = A.new a.asset_0 = 123 a.asset_0 # => 123 

详细信息请访问http://kinopyo.com/en/blog/ruby-include-module-with-arguments ,希望您会发现它很有用。

您无法将参数传递给模块。 实际上,除了发送消息之外,您不能将参数传递给任何内容。

所以,你必须使用一条消息发送:

 module Kernel private def Assetable(num) @__assetable_cache__ ||= [] @__assetable_cache__[num] ||= Module.new do num.times do |i| attr_accessor :"asset_#{i}" attr_accessible :"asset_#{i}" end end end end class Foo include Assetable 3 end 

注意:我根本不明白你为什么需要ActiveSupport::Concern ,但很容易重新加入。

您可以生成并包含匿名模块,而不会污染全局名称空间:

 module Assetable def self.[](argument) Module.new do extend ActiveSupport::Concern included do (argument).times do |i| attr_accessor :"asset_#{i}" attr_accessible :"asset_#{i}" end end end end end class Foo include Assetable[5] end