Class: ROM::Attribute

Inherits:
Object
  • Object
show all
Defined in:
core/lib/rom/attribute.rb

Overview

Schema attributes provide meta information about types and an API for additional operations. This class can be extended by adapters to provide database-specific features. In example rom-sql provides SQL::Attribute with more features like creating SQL expressions for queries.

Schema attributes are accessible through canonical relation schemas and instance-level schemas.

Constant Summary collapse

META_OPTIONS =
%i[primary_key foreign_key source target relation].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object (private)

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.

[View source]

410
411
412
413
414
415
416
417
418
419
420
421
422
# File 'core/lib/rom/attribute.rb', line 410

def method_missing(meth, *args, &block)
  if type.respond_to?(meth)
    response = type.__send__(meth, *args, &block)

    if response.is_a?(type.class)
      self.class.new(response, **options)
    else
      response
    end
  else
    super
  end
end

Instance Attribute Details

#nameSymbol (readonly)

Return the canonical name of this attribute name

This always returns the name that is used in the datastore, even when an attribute is aliased

Examples:

class Users < ROM::Relation[:memory]
  schema do
    attribute :user_id, Types::Integer, alias: :id
    attribute :email, Types::String
  end
end

users[:user_id].name
# => :user_id

users[:email].name
# => :email

Returns:

  • (Symbol)

55
# File 'core/lib/rom/attribute.rb', line 55

option :name, optional: true, type: Types::Strict::Symbol

#typeSymbol? (readonly)

Returns Alias to use instead of attribute name.

Returns:

  • (Symbol, nil)

    Alias to use instead of attribute name


29
# File 'core/lib/rom/attribute.rb', line 29

param :type

Instance Method Details

#aliased(name) ⇒ Attribute Also known as: as

Return new attribute type with provided alias

Examples:

class Tasks < ROM::Relation[:memory]
  schema do
    attribute :user_id, Types::Integer
    attribute :name, Types::String
  end
end

aliased_user_id = Users.schema[:user_id].aliased(:id)

aliased_user_id.aliased?
# => true

aliased_user_id.name
# => :user_id

aliased_user_id.alias
# => :id

Parameters:

  • name (Symbol)

    The alias

Returns:

[View source]

234
235
236
# File 'core/lib/rom/attribute.rb', line 234

def aliased(name)
  with(alias: name)
end

#aliased?TrueClass, FalseClass

Return true if this attribute has a configured alias

Examples:

class Tasks < ROM::Relation[:memory]
  schema do
    attribute :user_id, Types::Integer, alias: :id
    attribute :name, Types::String
  end
end

Users.schema[:user_id].aliased?
# => true

Users.schema[:name].aliased?
# => false

Returns:

  • (TrueClass, FalseClass)
[View source]

133
134
135
# File 'core/lib/rom/attribute.rb', line 133

def aliased?
  !self.alias.nil?
end

#eql?(other) ⇒ TrueClass, FalseClass

Check if the attribute type is equal to another

Parameters:

Returns:

  • (TrueClass, FalseClass)
[View source]

332
333
334
# File 'core/lib/rom/attribute.rb', line 332

def eql?(other)
  other.is_a?(self.class) ? super : type.eql?(other)
end

#foreign_key?TrueClass, FalseClass

Return true if this attribute type is a foreign key

Examples:

class Tasks < ROM::Relation[:memory]
  schema do
    attribute :id, Types::Integer
    attribute :user_id, Types.ForeignKey(:users)
  end
end

Users.schema[:user_id].foreign_key?
# => true

Users.schema[:id].foreign_key?
# => false

Returns:

  • (TrueClass, FalseClass)
[View source]

110
111
112
# File 'core/lib/rom/attribute.rb', line 110

def foreign_key?
  meta[:foreign_key].equal?(true)
end

#inspectString Also known as: pretty_inspect

Return string representation of the attribute type

Returns:

  • (String)
[View source]

318
319
320
321
322
# File 'core/lib/rom/attribute.rb', line 318

def inspect
  opts = options.reject { |k| %i[type name].include?(k) }
  meta_and_opts = meta.merge(opts).map { |k, v| "#{k}=#{v.inspect}" }
  %(#<#{self.class}[#{type.name}] name=#{name.inspect} #{meta_and_opts.join(' ')}>)
end

#keySymbol

Return tuple key

When schemas are projected with aliased attributes, we need a simple access to tuple keys

Examples:

class Tasks < ROM::Relation[:memory]
  schema do
    attribute :user_id, Types::Integer, alias: :id
    attribute :name, Types::String
  end
end

Users.schema[:id].key
# :id

Users.schema.project(Users.schema[:id].aliased(:user_id)).key
# :user_id

Returns:

  • (Symbol)
[View source]

204
205
206
# File 'core/lib/rom/attribute.rb', line 204

def key
  self.alias || name
end

#meta(opts = nil) ⇒ Attribute

Return attribute type with additional meta information

Return meta information hash if no opts are provided

Parameters:

  • opts (Hash) (defaults to: nil)

    The meta options

Returns:

[View source]

305
306
307
308
309
310
311
# File 'core/lib/rom/attribute.rb', line 305

def meta(opts = nil)
  if opts
    self.class.new(type.meta(opts), **options)
  else
    type.meta
  end
end

#optionalAttribute

Return nullable attribute

Returns:

[View source]

369
370
371
372
# File 'core/lib/rom/attribute.rb', line 369

def optional
  sum = self.class.new(super, **options)
  read? ? sum.meta(read: meta[:read].optional) : sum
end

#prefixed(prefix = source.dataset) ⇒ Attribute

Return new attribute type with an alias using provided prefix

Examples:

class Users < ROM::Relation[:memory]
  schema do
    attribute :id, Types::Integer
    attribute :name, Types::String
  end
end

prefixed_id = Users.schema[:id].prefixed

prefixed_id.aliased?
# => true

prefixed_id.name
# => :id

prefixed_id.alias
# => :users_id

prefixed_id = Users.schema[:id].prefixed(:user)

prefixed_id.alias
# => :user_id

Parameters:

  • prefix (Symbol) (defaults to: source.dataset)

    The prefix (defaults to source.dataset)

Returns:

[View source]

270
271
272
# File 'core/lib/rom/attribute.rb', line 270

def prefixed(prefix = source.dataset)
  aliased(:"#{prefix}_#{name}")
end

#primary_key?TrueClass, FalseClass

Return true if this attribute type is a primary key

Examples:

class Users < ROM::Relation[:memory]
  schema do
    attribute :id, Types::Integer
    attribute :name, Types::String

    primary_key :id
  end
end

Users.schema[:id].primary_key?
# => true

Users.schema[:name].primary_key?
# => false

Returns:

  • (TrueClass, FalseClass)
[View source]

87
88
89
# File 'core/lib/rom/attribute.rb', line 87

def primary_key?
  meta[:primary_key].equal?(true)
end

#sourceSymbol, Relation::Name

Return source relation of this attribute type

Examples:

class Tasks < ROM::Relation[:memory]
  schema do
    attribute :id, Types::Integer
    attribute :user_id, Types.ForeignKey(:users)
  end
end

Users.schema[:id].source
# => :tasks

Users.schema[:user_id].source
# => :tasks

Returns:

  • (Symbol, Relation::Name)
[View source]

156
157
158
# File 'core/lib/rom/attribute.rb', line 156

def source
  meta[:source]
end

#targetNilClass, ...

Return target relation of this attribute type

Examples:

class Tasks < ROM::Relation[:memory]
  schema do
    attribute :id, Types::Integer
    attribute :user_id, Types.ForeignKey(:users)
  end
end

Users.schema[:id].target
# => nil

Users.schema[:user_id].target
# => :users

Returns:

  • (NilClass, Symbol, Relation::Name)
[View source]

179
180
181
# File 'core/lib/rom/attribute.rb', line 179

def target
  meta[:target]
end

#to_astArray

Return AST for the type

Returns:

  • (Array)
[View source]

384
385
386
# File 'core/lib/rom/attribute.rb', line 384

def to_ast
  [:attribute, [name, type.to_ast(meta: false), meta_options_ast]]
end

#to_read_astArray

Return AST for the read type

Returns:

  • (Array)
[View source]

393
394
395
# File 'core/lib/rom/attribute.rb', line 393

def to_read_ast
  [:attribute, [name, to_read_type.to_ast(meta: false), meta_options_ast]]
end

#wrapped(name = source.dataset) ⇒ Attribute

Return attribute type wrapped for the specified relation name

Parameters:

  • name (Symbol) (defaults to: source.dataset)

    The name of the source relation (defaults to source.dataset)

Returns:

[View source]

292
293
294
# File 'core/lib/rom/attribute.rb', line 292

def wrapped(name = source.dataset)
  prefixed(name).meta(wrapped: true)
end

#wrapped?Boolean

Return if the attribute type is from a wrapped relation

Wrapped attributes are used when two schemas from different relations are merged together. This way we can identify them easily and handle correctly in places like auto-mapping.

Returns:

  • (Boolean)
[View source]

281
282
283
# File 'core/lib/rom/attribute.rb', line 281

def wrapped?
  meta[:wrapped].equal?(true)
end