Ruby on Rails, including a module with arguments

Is there a way to use the arguments when turning on the ruby โ€‹โ€‹module? I have an Assetable module that is included in many classes. I want you to be able to create attr_accessor on the fly.

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 
+7
ruby ruby-on-rails
source share
3 answers

There is no way to pass arguments when the module is turned on. It would be best to define a class method that allows you to subsequently create what you need:

 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." 

Also, be careful when overriding the included method as part of the problem, because it is also used by ActiveSupport::Concern . You must call super inside the overriden method to ensure proper initialization.

+13
source share

There is a trick: creating a class that inherits from the module so that you can pass any arguments to a module of type class.

 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 

Details are published on the blog http://kinopyo.com/en/blog/ruby-include-module-with-arguments , I hope you find this useful.

+15
source share

You cannot pass arguments to a module. In fact, you cannot pass arguments for anything other than sending a message.

So you should use message sending:

 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 

Note. I did not understand why you need ActiveSupport::Concern here at all, but it is easy to add it back.

+4
source share

All Articles