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
@!attribute [r] registry
@return [RelationRegistry] Relations registry from a rom container
@!attribute [r] source
@return [Relation::Name] The source relation
Public Class Methods
@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
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
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
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
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
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
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
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
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
@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
@api private
# File lib/rom/schema/associations_dsl.rb, line 201 def dataset_name(name) Inflector.pluralize(name).to_sym end