Module: BuilderSupport::ClassMethods

Defined in:
lib/builder_support.rb

Instance Method Summary collapse

Instance Method Details

#builder_add(*attrs, when: nil, name: nil, &block) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
# 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:) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 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 = { }) ⇒ Object



72
73
74
# File 'lib/builder_support.rb', line 72

def builder_map settings = { }
  (@builder_map ||= { }).merge! settings
end

#builder_rmv(*attrs) ⇒ Object



54
55
56
# File 'lib/builder_support.rb', line 54

def builder_rmv *attrs
  (@builder_rmv ||= [ ]).concat attrs
end

#flatten_attrs(rmv: [ ], add: [ ]) ⇒ Object



82
83
84
# File 'lib/builder_support.rb', line 82

def flatten_attrs(rmv: [ ], add: [ ])
  (@flatten_attrs ||= [ ]) - rmv + add
end

#generate_assoc_info_method(attrs) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# 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: [ ]) ⇒ Object



76
77
78
79
80
# 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: { }) ⇒ Object

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



50
51
52
# 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