Class: ROM::Mapper::AttributeDSL Private

Inherits:
Object
  • Object
show all
Includes:
ModelDSL
Defined in:
lib/rom/mapper/attribute_dsl.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Mapper attribute DSL exposed by mapper subclasses

This class is private even though its methods are exposed by mappers. Typically it’s not meant to be used directly.

TODO: break this madness down into smaller pieces

rubocop:disable Metrics/ClassLength

Constant Summary

Constants included from ModelDSL

ModelDSL::DEFAULT_TYPE

Instance Attribute Summary collapse

Attributes included from ModelDSL

#builder, #klass

Instance Method Summary collapse

Methods included from ModelDSL

#model

Constructor Details

#initialize(attributes, options) ⇒ AttributeDSL

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of AttributeDSL.



36
37
38
39
40
41
42
43
44
45
# File 'lib/rom/mapper/attribute_dsl.rb', line 36

def initialize(attributes, options)
  @attributes = attributes
  @options = options
  @copy_keys = options.fetch(:copy_keys)
  @symbolize_keys = options.fetch(:symbolize_keys)
  @prefix = options.fetch(:prefix)
  @prefix_separator = options.fetch(:prefix_separator)
  @reject_keys = options.fetch(:reject_keys)
  @steps = []
end

Instance Attribute Details

#attributesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



20
21
22
# File 'lib/rom/mapper/attribute_dsl.rb', line 20

def attributes
  @attributes
end

#copy_keysObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



24
25
26
# File 'lib/rom/mapper/attribute_dsl.rb', line 24

def copy_keys
  @copy_keys
end

#optionsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



22
23
24
# File 'lib/rom/mapper/attribute_dsl.rb', line 22

def options
  @options
end

#reject_keysObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



28
29
30
# File 'lib/rom/mapper/attribute_dsl.rb', line 28

def reject_keys
  @reject_keys
end

#stepsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



30
31
32
# File 'lib/rom/mapper/attribute_dsl.rb', line 30

def steps
  @steps
end

#symbolize_keysObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



26
27
28
# File 'lib/rom/mapper/attribute_dsl.rb', line 26

def symbolize_keys
  @symbolize_keys
end

Instance Method Details

#attribute(name, options = EMPTY_HASH, &block) ⇒ Object

Define a mapping attribute with its options and/or block

Examples:

dsl = AttributeDSL.new([])

dsl.attribute(:name)
dsl.attribute(:email, from: 'user_email')
dsl.attribute(:name) { 'John' }
dsl.attribute(:name) { |t| t.upcase }


90
91
92
93
94
95
96
97
98
99
# File 'lib/rom/mapper/attribute_dsl.rb', line 90

def attribute(name, options = EMPTY_HASH, &block)
  with_attr_options(name, options) do |attr_options|
    if options[:type] && block_given?
      raise ArgumentError,
            "can't specify type and block at the same time"
    end
    attr_options[:coercer] = block if block_given?
    add_attribute(name, attr_options)
  end
end

#combine(name, options) ⇒ Object

Define an embedded combined attribute that requires “combine” transformation

Typically this can be used to process results of eager-loading

Examples:

dsl = AttributeDSL.new([])

dsl.combine(:tags, user_id: :id) do
  model Tag

  attribute :name
end


344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/rom/mapper/attribute_dsl.rb', line 344

def combine(name, options, &)
  dsl = new(options, &)

  attr_opts = {
    type: options.fetch(:type, :array),
    keys: options.fetch(:on),
    combine: true,
    header: dsl.header
  }

  add_attribute(name, attr_opts)
end

#embedded(name, options) ⇒ Object

Define an embedded attribute

Block exposes the attribute dsl too

Examples:

dsl = AttributeDSL.new([])

dsl.embedded :tags, type: :array do
  attribute :name
end

dsl.embedded :address, type: :hash do
  model Address
  attribute :name
end

Options Hash (options):

  • :type (Symbol)

    Embedded type can be :hash or :array

  • :prefix (Symbol)

    Prefix that should be used for its attributes



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/rom/mapper/attribute_dsl.rb', line 143

def embedded(name, options, &)
  with_attr_options(name) do |attr_options|
    mapper = options[:mapper]

    if mapper
      embedded_options = { type: :array }.update(options)
      attributes_from_mapper(
        mapper, name, embedded_options.update(attr_options)
      )
    else
      dsl = new(options, &)
      attr_options.update(options)
      add_attribute(
        name, { header: dsl.header, type: :array }.update(attr_options)
      )
    end
  end
end

#exclude(name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



101
102
103
# File 'lib/rom/mapper/attribute_dsl.rb', line 101

def exclude(name)
  attributes << [name,  exclude: true]
end

#fold(*args) ⇒ Object

Define an embedded hash attribute that requires “fold” transformation

Typically this is used in sql context to fold single joined field to the array of values.

Examples:

dsl = AttributeDSL.new([])

dsl.fold(tags: [:name])

See Also:



288
289
290
291
292
293
# File 'lib/rom/mapper/attribute_dsl.rb', line 288

def fold(*args, &)
  with_name_or_options(*args) do |name, *|
    fold_options = { type: :array, fold: true }
    dsl(name, fold_options, &)
  end
end

#group(*args) ⇒ Object

Define an embedded hash attribute that requires “grouping” transformation

Typically this is used in sql context when relation is a join.

Examples:

dsl = AttributeDSL.new([])

dsl.group(tags: [:name])

dsl.group(:tags) do
  model Tag
  attribute :name
end

See Also:



243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/rom/mapper/attribute_dsl.rb', line 243

def group(*args, &)
  ensure_mapper_configuration('group', args, block_given?)

  with_name_or_options(*args) do |name, options, mapper|
    group_options = { type: :array, group: true }.update(options)

    if mapper
      attributes_from_mapper(mapper, name, group_options)
    else
      dsl(name, group_options, &)
    end
  end
end

#headerHeader

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generate a header from attribute definitions



362
363
364
# File 'lib/rom/mapper/attribute_dsl.rb', line 362

def header
  Header.coerce(attributes, copy_keys: copy_keys, model: model, reject_keys: reject_keys)
end

#prefix(value = Undefined) ⇒ Object

Redefine the prefix for the following attributes

Examples:


dsl = AttributeDSL.new([])
dsl.attribute(:prefix, 'user')


55
56
57
58
59
60
61
# File 'lib/rom/mapper/attribute_dsl.rb', line 55

def prefix(value = Undefined)
  if value.equal?(Undefined)
    @prefix
  else
    @prefix = value
  end
end

#prefix_separator(value = Undefined) ⇒ Object

Redefine the prefix separator for the following attributes

Examples:


dsl = AttributeDSL.new([])
dsl.attribute(:prefix_separator, '.')


71
72
73
74
75
76
77
# File 'lib/rom/mapper/attribute_dsl.rb', line 71

def prefix_separator(value = Undefined)
  if value.equal?(Undefined)
    @prefix_separator
  else
    @prefix_separator = value
  end
end

#step(options = EMPTY_HASH) ⇒ Object

Perform transformations sequentially

Examples:

dsl = AttributeDSL.new()

dsl.step do
  attribute :name
end


115
116
117
# File 'lib/rom/mapper/attribute_dsl.rb', line 115

def step(options = EMPTY_HASH, &)
  steps << new(options, &)
end

#unfold(name, options = EMPTY_HASH) ⇒ Object

Define an embedded hash attribute that requires “unfold” transformation

Typically this is used in non-sql context to convert array of values (like in Cassandra ‘SET’ or ‘LIST’ types) to array of tuples.

Source values are assigned to the first key, the other keys being left blank.

Examples:

dsl = AttributeDSL.new([])

dsl.unfold(tags: [:name, :type], from: :tags_list)

dsl.unfold :tags, from: :tags_list do
  attribute :name, from: :tag_name
  attribute :type, from: :tag_type
end

See Also:



315
316
317
318
319
320
321
322
323
# File 'lib/rom/mapper/attribute_dsl.rb', line 315

def unfold(name, options = EMPTY_HASH)
  with_attr_options(name, options) do |attr_options|
    old_name = attr_options.fetch(:from, name)
    dsl(old_name, type: :array, unfold: true) do
      attribute name, attr_options
      yield if block_given?
    end
  end
end

#ungroup(*args) ⇒ Object

Define an embedded array attribute that requires “ungrouping” transformation

Typically this is used in non-sql context being prepared for import to sql.

Examples:

dsl = AttributeDSL.new([])
dsl.ungroup(tags: [:name])

See Also:



268
269
270
271
272
273
# File 'lib/rom/mapper/attribute_dsl.rb', line 268

def ungroup(*args, &)
  with_name_or_options(*args) do |name, options, *|
    ungroup_options = { type: :array, ungroup: true }.update(options)
    dsl(name, ungroup_options, &)
  end
end

#unwrap(*args) ⇒ Object

Define an embedded hash attribute that requires “unwrapping” transformation

Typically this is used in no-sql context to normalize data before inserting to sql gateway.

Examples:

dsl = AttributeDSL.new([])

dsl.unwrap(address: [:street, :zipcode, :city])

dsl.unwrap(:address) do
  attribute :street
  attribute :zipcode
  attribute :city
end

See Also:



214
215
216
217
218
219
220
221
222
223
224
# File 'lib/rom/mapper/attribute_dsl.rb', line 214

def unwrap(*args, &)
  with_name_or_options(*args) do |name, options, mapper|
    unwrap_options = { type: :hash, unwrap: true }.update(options)

    if mapper
      attributes_from_mapper(mapper, name, unwrap_options)
    else
      dsl(name, unwrap_options, &)
    end
  end
end

#wrap(*args) ⇒ Object

Define an embedded hash attribute that requires “wrapping” transformation

Typically this is used in sql context when relation is a join.

Examples:

dsl = AttributeDSL.new([])

dsl.wrap(address: [:street, :zipcode, :city])

dsl.wrap(:address) do
  model Address
  attribute :street
  attribute :zipcode
  attribute :city
end

See Also:



181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/rom/mapper/attribute_dsl.rb', line 181

def wrap(*args, &)
  ensure_mapper_configuration('wrap', args, block_given?)

  with_name_or_options(*args) do |name, options, mapper|
    wrap_options = { type: :hash, wrap: true }.update(options)

    if mapper
      attributes_from_mapper(mapper, name, wrap_options)
    else
      dsl(name, wrap_options, &)
    end
  end
end