module BuilderSupport::ClassMethods

Public Instance Methods

builder_add(*attrs, when: nil, name: nil, &block) click to toggle source
# File lib/builder_support.rb, line 58
def builder_add *attrs, when: nil, name: nil, &block
  define_method(attrs.first) { instance_eval(&block) } if block_given?
  builder_map attrs[0] => name if name

  if (w = binding.local_variable_get(:when))
    builder_add_with_when attrs[0], when: w
  elsif attrs.delete(:flatten)
    (@flatten_attrs ||= [ ]).concat attrs
  else
    (@builder_add ||= [ ]).concat attrs
    generate_assoc_info_method attrs
  end
end
builder_add_with_when(attr, when:) click to toggle source
# File lib/builder_support.rb, line 86
def builder_add_with_when(attr, when:)
  w = binding.local_variable_get(:when)
  # 生成 when 设置的同名函数
  # 用以设置状态
  if w.is_a? Symbol
    define_singleton_method w do
      all.to_a.to_builder(add: [attr])
    end
  else # is proc
    (@builder_add_dynamically ||= { })[attr] = w
  end

  generate_assoc_info_method attr
end
builder_map(settings = { }) click to toggle source
# File lib/builder_support.rb, line 72
def builder_map settings = { }
  (@builder_map ||= { }).merge! settings
end
builder_rmv(*attrs) click to toggle source
# File lib/builder_support.rb, line 54
def builder_rmv *attrs
  (@builder_rmv ||= [ ]).concat attrs
end
flatten_attrs(rmv: [ ], add: [ ]) click to toggle source
# File lib/builder_support.rb, line 82
def flatten_attrs(rmv: [ ], add: [ ])
  (@flatten_attrs ||= [ ]) - rmv + add
end
generate_assoc_info_method(attrs) click to toggle source
# File lib/builder_support.rb, line 101
def generate_assoc_info_method(attrs)
  # 匹配关联模型 `name_info` 形式的 attr,并自动生成该方法
  # 方法调用模型的 to_builder 方法并取得最终渲染结果
  # unscoped 主要是为了支持去除软删除的默认 scope
  Array(attrs).each do |attr|
    next unless attr.to_s.match?(/_info/)
    assoc_method = attr.to_s.gsub('_info', '')
    next unless new.respond_to?(assoc_method) rescue next

    define_method attr do
      send(assoc_method)&.to_builder || nil
    end

    assoc_model = assoc_method.to_s.singularize
    builder_rmv "#{assoc_model}_id".to_sym
  end
end
show_attrs(rmv: [ ], add: [ ]) click to toggle source
# File lib/builder_support.rb, line 76
def show_attrs(rmv: [ ], add: [ ])
  self.column_names.map(&:to_sym) \
      - (@builder_rmv || [ ]) - rmv \
      + (@builder_add || [ ]) + add
end
to_builder(rmv: [ ], add: [ ], merge: { }) click to toggle source

FIXME: 很奇怪的 scope 影响,尽量用转成 arr 的 to_bd 而不是直接调

# File lib/builder_support.rb, line 50
def to_builder(rmv: [ ], add: [ ], merge: { })
  all.to_a.to_builder(rmv: rmv, add: add, merge: merge)
end