class ROM::Schema::AssociationsDSL

Additional schema DSL for definition SQL associations

This DSL is exposed in `associations do .. end` blocks in schema defintions.

@api public

Attributes

registry[R]

@!attribute [r] registry

@return [RelationRegistry] Relations registry from a rom container
source[R]

@!attribute [r] source

@return [Relation::Name] The source relation

Public Class Methods

new(source, &block) click to toggle source

@api private

# File lib/rom/schema/associations_dsl.rb, line 24
def initialize(source, &block)
  @source = source
  @registry = {}
  instance_exec(&block)
end

Public Instance Methods

belongs_to(target, **options) click to toggle source

Shortcut for many_to_one which sets alias automatically

@example with an alias (relation identifier is inferred via pluralization)

belongs_to :user

@example with an explicit alias

belongs_to :users, as: :author

@see many_to_one

@return [Associations::ManyToOne]

@api public

# File lib/rom/schema/associations_dsl.rb, line 154
def belongs_to(target, **options)
  many_to_one(dataset_name(target), as: target, **options)
end
call() click to toggle source

Return an association set for a schema

@return [AssociationSet]

@api private

# File lib/rom/schema/associations_dsl.rb, line 180
def call
  AssociationSet[source.relation].build(registry)
end
has_many(target, **options)
Alias for: one_to_many
has_one(target, **options) click to toggle source

Shortcut for one_to_one which sets alias automatically

@example with an alias (relation identifier is inferred via pluralization)

has_one :address

@example with an explicit alias and a custom view

has_one :posts, as: :priority_post, view: :prioritized

@see one_to_one

@return [Associations::OneToOne]

@api public

# File lib/rom/schema/associations_dsl.rb, line 171
def has_one(target, **options)
  one_to_one(dataset_name(target), as: target, **options)
end
many_to_many(target, **options) click to toggle source

Establish a many-to-many association

@example using relation identifier

many_to_many :tasks, through: :users_tasks

@param [Symbol] target The target relation identifier @param [Hash] options A hash with additional options

@return [Associations::ManyToMany]

@see one_to_many

@api public

# File lib/rom/schema/associations_dsl.rb, line 120
def many_to_many(target, **options)
  add(::ROM::Associations::Definitions::ManyToMany.new(source, target, **options))
end
many_to_one(target, **options) click to toggle source

Establish a many-to-one association

@example using relation identifier

many_to_one :users, as: :author

@param [Symbol] target The target relation identifier @param [Hash] options A hash with additional options

@return [Associations::ManyToOne]

@see one_to_many

@api public

# File lib/rom/schema/associations_dsl.rb, line 137
def many_to_one(target, **options)
  add(::ROM::Associations::Definitions::ManyToOne.new(source, target, **options))
end
one_to_many(target, **options) click to toggle source

Establish a one-to-many association

@example using relation identifier

has_many :tasks

@example setting custom foreign key name

has_many :tasks, foreign_key: :assignee_id

@example with a :through option

# this establishes many-to-many association
has_many :tasks, through: :users_tasks

@example using a custom view which overrides default one

has_many :posts, view: :published, override: true

@example using aliased association with a custom view

has_many :posts, as: :published_posts, view: :published

@example using custom target relation

has_many :user_posts, relation: :posts

@example using custom target relation and an alias

has_many :user_posts, relation: :posts, as: :published, view: :published

@param [Symbol] target The target relation identifier @param [Hash] options A hash with additional options

@return [Associations::OneToMany]

@see many_to_many

@api public

# File lib/rom/schema/associations_dsl.rb, line 62
def one_to_many(target, **options)
  if options[:through]
    many_to_many(target, **options)
  else
    add(::ROM::Associations::Definitions::OneToMany.new(source, target, **options))
  end
end
Also aliased as: has_many
one_to_one(target, **options) click to toggle source

Establish a one-to-one association

@example using relation identifier

one_to_one :addresses, as: :address

@example with an intermediate join relation

one_to_one :tasks, as: :priority_task, through: :assignments

@param [Symbol] target The target relation identifier @param [Hash] options A hash with additional options

@return [Associations::OneToOne]

@see belongs_to

@api public

# File lib/rom/schema/associations_dsl.rb, line 87
def one_to_one(target, **options)
  if options[:through]
    one_to_one_through(target, **options)
  else
    add(::ROM::Associations::Definitions::OneToOne.new(source, target, **options))
  end
end
one_to_one_through(target, **options) click to toggle source

Establish a one-to-one association with a :through option

@example

one_to_one_through :users, as: :author, through: :users_posts

@return [Associations::OneToOneThrough]

@api public

# File lib/rom/schema/associations_dsl.rb, line 103
def one_to_one_through(target, **options)
  add(::ROM::Associations::Definitions::OneToOneThrough.new(source, target, **options))
end

Private Instance Methods

add(association) click to toggle source

@api private

# File lib/rom/schema/associations_dsl.rb, line 187
def add(association)
  key = association.as || association.name

  if registry.key?(key)
    ::Kernel.raise(
      ::ArgumentError,
      "association #{key.inspect} is already defined for #{source.to_sym.inspect} relation"
    )
  end

  registry[key] = association
end
dataset_name(name) click to toggle source

@api private

# File lib/rom/schema/associations_dsl.rb, line 201
def dataset_name(name)
  Inflector.pluralize(name).to_sym
end