我想通过 ActiveSupport::Concern
将一个 module 里的实例方法引入到 module 中,但发现在 include 后,不能马上使用这个方法。
代码如下:
# writable.rb
module Writable
extend ActiveSupport::Concern
included do
attr_reader :write_worker
end
def set_options(worker)
@worker = worker
end
end
# user.rb
class User < ApplicationRecord
include Writable
set_options("UserWorker") # 这里因为每个model需要传入不同的参数,所在需要单独在每个被include的model中调用
end
这时候我去 new 这个类的时候会出错,找不到 set_options 方法
# console
user = User.new
# => undefined method `set_options' for #<Class:0x007f909bec0508>
如果我把这个方法放在 after_initialize
里,就可以正常,但感觉很啰嗦
# user.rb
class User < ApplicationRecord
include Writable
after_initialize do
set_options(xxxx)
end
end
请问有没有办法在不使用 after_initialize
的情况下让代码晚优雅简练地达到目的?
之前搞错了概念,用如下方式就可以在实例方法里取类成员属性,不用加 after_initialize
了。
module Workable
def self.included(base)
base.extend ClassMethods
#include InstanceMethods
base.send(:include, InstanceMethods)
end
module ClassMethods
attr_reader :worker
def set_options(worker: nil)
@worker = worker
end
end
module InstanceMethods
def get_options
puts "worker: #{self.class.worker}"
end
end
end
class Test
include Workable
set_options(worker: 'worker1')
end
class Test2
include Workable
set_options(worker: 'worker2')
end
Test.new.get_options # => worker1
Test2.new.get_options # => worker2