我正在尝试编写使用代码块的类方法 my_method (如验证)。
模型包含下一个代码:
class Model < ActiveRecord::Base
include Usable
my_method :arg_1, :arg_2
my_method do |model|
# just for example
if model.attribute.present?
:arg3
else
:arg4
end
end
#...
end
my_method 是关注定义的类方法:
module Usable
extend ActiveSupport::Concern
# instance methods
def instance_method
self.class.display_attrs
end
# ...
module ClassMethods
# class methods
def display_attrs
@attrs_for_display ||= []
end
def my_method(*attr_names, &block)
attr_names.each do |attr|
attr_data = { attr: attr }
display_attrs << attr_data
end
display_attrs << { attr: block} if block_given?
end
end
end
实例方法@ model.instance_method在 my_method 直接放入my_method :arg_1, :arg_2
> Model.last.instance_method
=> [{:attr=>:arg_1}, {:attr=>:arg_2}]
但当 my_method 使用块my_method {:arg_3}
> Model.last.instance_method
=>[{:attr=> #<Proc:0x00 ... >}]
如何根据实例状态输入 my_method 参数?例如,@model.instance_method
应该返回:arg_3 if model.attribute.present?
答案 0 :(得分:1)
问题已通过call method解决。 我重写了instance_method如下:
def instance_method
class_attrs = self.class.display_attrs.map { |n| n[:attr] }
class_blocks = self.class.display_attrs.map { |n| n[:block].call(self) if n[:block] }
(class_attrs + class_blocks).compact!
end
module ClassMethods
#...
display_attrs << { block: block} if block_given?
#...
end