# File lib/rom/attribute.rb, line 87 def primary_key? meta[:primary_key].equal?(true) end
class ROM::Attribute
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.
@api public
Constants
- META_OPTIONS
Public Instance Methods
@api private
# File lib/rom/attribute.rb, line 62 def [](value = Undefined) type[value] end
Return new attribute type with provided alias
@example
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
@param [Symbol] name The alias
@return [Attribute]
@api public
# File lib/rom/attribute.rb, line 234 def aliased(name) with(alias: name) end
Return true if this attribute has a configured alias
@example
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
@return [TrueClass,FalseClass]
@api public
# File lib/rom/attribute.rb, line 133 def aliased? !self.alias.nil? end
Check if the attribute type is equal to another
@param [Dry::Type, Attribute] other
@return [TrueClass,FalseClass]
@api public
# File lib/rom/attribute.rb, line 332 def eql?(other) other.is_a?(self.class) ? super : type.eql?(other) end
Return true if this attribute type is a foreign key
@example
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
@return [TrueClass,FalseClass]
@api public
# File lib/rom/attribute.rb, line 110 def foreign_key? meta[:foreign_key].equal?(true) end
Return string representation of the attribute type
@return [String]
@api public
# File 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
Return tuple key
When schemas are projected with aliased attributes, we need a simple access to tuple keys
@example
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
@return [Symbol]
@api public
# File lib/rom/attribute.rb, line 204 def key self.alias || name end
Return attribute type with additional meta information
Return meta information hash if no opts are provided
@param [Hash] opts The meta options
@return [Attribute]
@api public
# File lib/rom/attribute.rb, line 305 def meta(opts = nil) if opts self.class.new(type.meta(opts), **options) else type.meta end end
@api private
# File lib/rom/attribute.rb, line 398 def meta_options_ast keys = %i[wrapped primary_key alias] ast = meta.merge(options).select { |k, _| keys.include?(k) } ast[:source] = source.to_sym if source ast end
Return nullable attribute
@return [Attribute]
@api public
# File lib/rom/attribute.rb, line 369 def optional sum = self.class.new(super, **options) read? ? sum.meta(read: meta[:read].optional) : sum end
Return new attribute type with an alias using provided prefix
@example
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
@param [Symbol] prefix The prefix (defaults to source.dataset)
@return [Attribute]
@api public
# File lib/rom/attribute.rb, line 270 def prefixed(prefix = source.dataset) aliased(:"#{prefix}_#{name}") end
Return true if this attribute type is a primary key
@example
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
@return [TrueClass,FalseClass]
@api public
Return if this attribute type has additional attribute type for reading tuple values
@return [TrueClass, FalseClass]
@api private
# File lib/rom/attribute.rb, line 342 def read? !meta[:read].nil? end
@api private
# File lib/rom/attribute.rb, line 375 def respond_to_missing?(name, include_private = false) type.respond_to?(name) || super end
Return source relation of this attribute type
@example
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
@return [Symbol, Relation::Name]
@api public
# File lib/rom/attribute.rb, line 156 def source meta[:source] end
Return target relation of this attribute type
@example
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
@return [NilClass, Symbol, Relation::Name]
@api public
# File lib/rom/attribute.rb, line 179 def target meta[:target] end
Return AST for the type
@return [Array]
@api public
# File lib/rom/attribute.rb, line 384 def to_ast [:attribute, [name, type.to_ast(meta: false), meta_options_ast]] end
Return AST for the read type
@return [Array]
@api public
# File lib/rom/attribute.rb, line 393 def to_read_ast [:attribute, [name, to_read_type.to_ast(meta: false), meta_options_ast]] end
Return read type
@return [Dry::Types::Type]
@api private
# File lib/rom/attribute.rb, line 351 def to_read_type read? ? meta[:read] : type end
Return write type
@return [Dry::Types::Type]
@api private
# File lib/rom/attribute.rb, line 360 def to_write_type type end
Return attribute type wrapped for the specified relation name
@param [Symbol] name The name of the source relation (defaults to source.dataset)
@return [Attribute]
@api public
# File lib/rom/attribute.rb, line 292 def wrapped(name = source.dataset) prefixed(name).meta(wrapped: true) end
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.
@api public
# File lib/rom/attribute.rb, line 281 def wrapped? meta[:wrapped].equal?(true) end
Private Instance Methods
@api private
# File 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