class ROM::Schema::DSL

Schema DSL exposed as `schema { .. }` in relation classes

@api public

Constants

KERNEL_METHODS

Attributes

associations_dsl[R]

@!attribute [r] associations_dsl

@return [AssociationDSL] Associations defined within a block
attributes[R]

@!attribute [r] attributes

@return [Hash<Symbol, Hash>] A hash with attribute names as
keys and attribute representations as values.

@see [Schema.build_attribute_info]
definition[R]

@!attribute [r] definition

@return [Proc] Definition block passed to DSL
plugins[R]

@!attribute [r] plugins

@return [Hash] A hash with schema plugins enabled in a schema

Public Class Methods

new(*, &block) click to toggle source

@api private

Calls superclass method
# File lib/rom/schema/dsl.rb, line 60
def initialize(*, &block)
  super

  @attributes = {}
  @plugins = {}

  @definition = block
end

Public Instance Methods

app_plugin(plugin, options = ::ROM::EMPTY_HASH) click to toggle source

@api private

# File lib/rom/schema/dsl.rb, line 178
def app_plugin(plugin, options = ::ROM::EMPTY_HASH)
  plugin.extend_dsl(self)
  @plugins[plugin.name] = [plugin, plugin.config.to_hash.merge(options)]
end
associations(&block) click to toggle source

Define associations for a relation

@example

class Users < ROM::Relation[:sql]
  schema(infer: true) do
    associations do
      has_many :tasks
      has_many :posts
      has_many :posts, as: :priority_posts, view: :prioritized
      belongs_to :account
    end
  end
end

class Posts < ROM::Relation[:sql]
  schema(infer: true) do
    associations do
      belongs_to :users, as: :author
    end
  end

  view(:prioritized) do
    where { priority <= 3 }
  end
end

@return [AssociationDSL]

@api public

# File lib/rom/schema/dsl.rb, line 117
def associations(&block)
  @associations_dsl = AssociationsDSL.new(relation, &block)
end
attribute(name, type_or_options, options = EMPTY_HASH) click to toggle source

Defines a relation attribute with its type and options.

When only options are given, type is left as nil. It makes sense when it is used alongside an schema inferrer, which will populate the type.

@see Relation.schema

@api public

# File lib/rom/schema/dsl.rb, line 79
def attribute(name, type_or_options, options = EMPTY_HASH)
  if attributes.key?(name)
    ::Kernel.raise ::ROM::AttributeAlreadyDefinedError,
                   "Attribute #{name.inspect} already defined"
  end

  attributes[name] = build_attribute_info(name, type_or_options, options)
end
build_attribute_info(name, type_or_options, options = EMPTY_HASH) click to toggle source

Builds a representation of the information needed to create an attribute. It returns a hash with `:type` and `:options` keys.

@return [Hash]

@see [Schema.build_attribute_info]

@api private

# File lib/rom/schema/dsl.rb, line 129
def build_attribute_info(name, type_or_options, options = EMPTY_HASH)
  type, options = if type_or_options.is_a?(::Hash)
                    [nil, type_or_options]
                  else
                    [build_type(type_or_options, options), options]
                  end
  Schema.build_attribute_info(
    type, **options, name: name
  )
end
build_type(type, options = EMPTY_HASH) click to toggle source

Builds a type instance from base type and meta options

@return [Dry::Types::Type] Type instance

@api private

# File lib/rom/schema/dsl.rb, line 145
def build_type(type, options = EMPTY_HASH)
  if options[:read]
    type.meta(source: relation, read: options[:read])
  elsif type.optional? && type.meta[:read]
    type.meta(source: relation, read: type.meta[:read].optional)
  else
    type.meta(source: relation)
  end.meta(Attribute::META_OPTIONS.map { |opt| [opt, options[opt]] if options.key?(opt) }.compact.to_h)
end
call(&block) click to toggle source

@api private

# File lib/rom/schema/dsl.rb, line 184
def call(&block)
  instance_exec(&block) if block
  instance_exec(&definition) if definition

  schema_class.define(relation, **opts) do |schema|
    plugins.values.each do |plugin, options|
      plugin.apply_to(schema, **options)
    end
  end
end
plugin_options(plugin) click to toggle source

@api private

# File lib/rom/schema/dsl.rb, line 196
def plugin_options(plugin)
  @plugins[plugin][1]
end
primary_key(*names) click to toggle source

Specify which key(s) should be the primary key

@api public

# File lib/rom/schema/dsl.rb, line 158
def primary_key(*names)
  names.each do |name|
    attributes[name][:type] =
      attributes[name][:type].meta(primary_key: true)
  end
  self
end
use(plugin_name, options = ::ROM::EMPTY_HASH) click to toggle source

Enables for the schema

@param [Symbol] plugin_name Plugin name @param [Hash] options Plugin options

@api public

# File lib/rom/schema/dsl.rb, line 172
def use(plugin_name, options = ::ROM::EMPTY_HASH)
  plugin = ::ROM.plugin_registry[:schema].fetch(plugin_name, adapter)
  app_plugin(plugin, options)
end

Private Instance Methods

opts() click to toggle source

Return schema opts

@return [Hash]

@api private

# File lib/rom/schema/dsl.rb, line 207
def opts
  opts = { attributes: attributes.values, inferrer: inferrer, attr_class: attr_class }

  if associations_dsl
    { **opts, associations: associations_dsl.call }
  else
    opts
  end
end