# 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
class ROM::Schema::DSL
Schema
DSL
exposed as `schema { .. }` in relation classes
@api public
Constants
- KERNEL_METHODS
Attributes
@!attribute [r] associations_dsl
@return [AssociationDSL] Associations defined within a block
@!attribute [r] attributes
@return [Hash<Symbol, Hash>] A hash with attribute names as keys and attribute representations as values. @see [Schema.build_attribute_info]
@!attribute [r] definition
@return [Proc] Definition block passed to DSL
@!attribute [r] plugins
@return [Hash] A hash with schema plugins enabled in a schema
Public Class Methods
@api private
# File lib/rom/schema/dsl.rb, line 60 def initialize(*, &block) super @attributes = {} @plugins = {} @definition = block end
Public Instance Methods
@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
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
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
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
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
@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
@api private
# File lib/rom/schema/dsl.rb, line 196 def plugin_options(plugin) @plugins[plugin][1] end
Specify which key(s) should be the primary key
@api public
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
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