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.

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.



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

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)


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

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



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

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:



232
233
234
# File 'core/lib/rom/attribute.rb', line 232

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)


131
132
133
# File 'core/lib/rom/attribute.rb', line 131

def aliased?
  !self.alias.nil?
end

#eql?(other) ⇒ TrueClass, FalseClass

Check if the attribute type is equal to another

Parameters:

Returns:

  • (TrueClass, FalseClass)


330
331
332
# File 'core/lib/rom/attribute.rb', line 330

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)


108
109
110
# File 'core/lib/rom/attribute.rb', line 108

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

#inspectString Also known as: pretty_inspect

Return string representation of the attribute type

Returns:

  • (String)


316
317
318
319
320
# File 'core/lib/rom/attribute.rb', line 316

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)


202
203
204
# File 'core/lib/rom/attribute.rb', line 202

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:



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

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

#optionalAttribute

Return nullable attribute

Returns:



367
368
369
370
# File 'core/lib/rom/attribute.rb', line 367

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:



268
269
270
# File 'core/lib/rom/attribute.rb', line 268

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)


85
86
87
# File 'core/lib/rom/attribute.rb', line 85

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)


154
155
156
# File 'core/lib/rom/attribute.rb', line 154

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)


177
178
179
# File 'core/lib/rom/attribute.rb', line 177

def target
  meta[:target]
end

#to_astArray

Return AST for the type

Returns:

  • (Array)


382
383
384
# File 'core/lib/rom/attribute.rb', line 382

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)


391
392
393
# File 'core/lib/rom/attribute.rb', line 391

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:



290
291
292
# File 'core/lib/rom/attribute.rb', line 290

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)


279
280
281
# File 'core/lib/rom/attribute.rb', line 279

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