Module: SimpleMaster::Master::Dsl

Included in:
SimpleMaster::Master
Defined in:
lib/simple_master/master/dsl.rb

Overview

Items declared at class-definition time are grouped inside this module

Constant Summary collapse

TYPES_BY_OPTIONS =
{
  polymorphic_type: Column::PolymorphicTypeColumn,
  sti: Column::StiTypeColumn,
  enum: Column::EnumColumn,
  bitmask: Column::BitmaskColumn,
}.freeze

Instance Method Summary collapse

Instance Method Details

#belongs_to(name, options = EMPTY_HASH) ⇒ Object



47
48
49
50
51
52
53
54
55
56
# File 'lib/simple_master/master/dsl.rb', line 47

def belongs_to(name, options = EMPTY_HASH)
  ass =
    if options[:polymorphic]
      Association::BelongsToPolymorphicAssociation.new(self, name, options)
    else
      Association::BelongsToAssociation.new(self, name, options)
    end

  belongs_to_associations << ass
end

#bitmask(name, options = Association) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/simple_master/master/dsl.rb', line 93

def bitmask(name, options = Association)
  proc {
    update_column_info(name) do |column|
      Column::BitmaskColumn.new(name, column.options.merge(bitmask: options[:as]))
    end
  }.tap { dsl_initializers << _1 }
end

#cache_attribute(method_name) ⇒ Object

  • Cache generated at load time and stored in an instance variable. Lightweight, but must not reference the dataset, so use with care. Intended for caches derived from record attributes.

    cache_attribute method_name_symbol
    
  • Can also be declared using the return value of a def:

    cache_attribute def method_name
      ...
    end
    
  • Passing a block generates the cache from the block.

cache_attribute method_name { … }



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/simple_master/master/dsl.rb', line 171

def cache_attribute(method_name, &)
  calc_method_name = :"_attribute_cache_#{method_name}"

  if block_given?
    define_method(calc_method_name, &)
  else
    alias_method calc_method_name, method_name
  end

  class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def #{method_name}
      return @#{method_name} if defined? @#{method_name}

      @#{method_name} = #{calc_method_name}
    end
  RUBY

  tap_instance_method method_name
end

#cache_class_method(*args, &block) ⇒ Object Also known as: def_custom_cache

  • Cache generated at load time and stored in the dataset.

    cache_class_method method_name_symbol
    
  • Can also be declared using the return value of a def:

    cache_class_method def self.method_name
      ...
    end
    
  • Pass a block to generate the cache from the block instead of an existing method.

    cache_class_method method_name_symbol { ... }
    
  • Defines class methods; multiple caches can be generated by passing several args.

    cache_class_method(:cache1, :cache2) {
      ...
      [cache1, cache2]
    }
    


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/simple_master/master/dsl.rb', line 130

def cache_class_method(*args, &block)
  @class_method_cache_info ||= []
  if block_given?
    @class_method_cache_info << [args, block]
  else
    args.each do |arg|
      method_name = :"_class_cache_#{arg}"
      @class_method_cache_info << [[arg], method_name]
      singleton_class.alias_method method_name, arg
    end
  end

  args.each do |arg|
    define_singleton_method(arg) do
      class_method_cache[arg]
    end
  end
end

#cache_method(method_name) ⇒ Object

  • Cache generated at load time and stored in the dataset. Heavier than cache_attribute because it uses the dataset.

    cache_method method_name_symbol
    
  • Can also be declared using the return value of a def:

    cache_method def method_name
      ...
    end
    
  • Passing a block generates the cache from the block.

    cache_method method_name_symbol { ... }
    


205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/simple_master/master/dsl.rb', line 205

def cache_method(method_name, &)
  calc_method_name = :"_method_cache_#{method_name}"
  if block_given?
    define_method(calc_method_name, &)
  else
    alias_method calc_method_name, method_name
  end

  class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def #{method_name}
      self.class.method_cache[:#{method_name}].fetch(self) {
        self.class.method_cache[:#{method_name}][self] = #{calc_method_name}
      }
    end
  RUBY

  tap_instance_method method_name
end

#def_column(column_name, options = {}) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/simple_master/master/dsl.rb', line 14

def def_column(column_name, options = {})
  column = column_type(column_name, options).new(column_name, options)
  columns << column

  if options[:sti]
    class_eval <<-RUBY, __FILE__, __LINE__ + 1
      def self.sti_base_class
        #{name}
      end

      def self.sti_column
        :#{column_name}
      end
    RUBY
  end
end

#enum(*args) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/simple_master/master/dsl.rb', line 68

def enum(*args)
  if args.length == 1
    options = args.first
    proc {
      options.each do |name, enums|
        update_column_info(name) do |column|
          Column::EnumColumn.new(name, column.options.merge(enum: enums))
        end
      end
    }.tap { dsl_initializers << _1 }
  elsif args.length >= 2
    name = args.shift
    enums = args.shift
    options = args.shift || {}

    proc {
      update_column_info(name) do |column|
        Column::EnumColumn.new(name, column.options.merge(options.merge(enum: enums)))
      end
    }.tap { dsl_initializers << _1 }
  else
    fail
  end
end

#globalize(column_name) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/simple_master/master/dsl.rb', line 101

def globalize(column_name)
  proc {
    update_column_info(column_name) do |column|
      column.options[:globalize] = true
      column
    end
  }.tap { dsl_initializers << _1 }
end

#group_key(column_name) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/simple_master/master/dsl.rb', line 58

def group_key(column_name)
  proc {
    update_column_info(column_name) do |column|
      column.group_key = true

      column
    end
  }.tap { dsl_initializers << _1 }
end

#has_many(name, options = {}) ⇒ Object



36
37
38
39
40
41
42
43
44
45
# File 'lib/simple_master/master/dsl.rb', line 36

def has_many(name, options = {})
  ass =
    if options[:through]
      Association::HasManyThroughAssociation.new(self, name, options)
    else
      Association::HasManyAssociation.new(self, name, options)
    end

  has_many_associations << ass
end

#has_one(name, options = EMPTY_HASH) ⇒ Object



31
32
33
34
# File 'lib/simple_master/master/dsl.rb', line 31

def has_one(name, options = EMPTY_HASH)
  ass = Association::HasOneAssociation.new(self, name, options)
  has_one_associations << ass
end

#tap_instance_method(method_name) ⇒ Object

Access the method once after the record is loaded



152
153
154
155
# File 'lib/simple_master/master/dsl.rb', line 152

def tap_instance_method(method_name)
  @instance_methods_need_tap ||= []
  @instance_methods_need_tap << method_name
end