Module: Sequel::Model::Associations

Included in:
Sequel::Model
Defined in:
lib/sequel_model/associations.rb

Overview

Associations are used in order to specify relationships between model classes that reflect relations between tables in the database using foreign keys.

Each kind of association adds a number of methods to the model class which are specialized according to the association type and optional parameters given in the definition. Example:

class Project < Sequel::Model
  belongs_to :portfolio
  has_many   :milestones
end

The project class now has the following methods:

  • Project#portfolio, Project#portfolio=

  • Project#milestones, Project#add_milestone, Project#remove_milestone

By default the classes for the associations are inferred from the association name, so for example the Project#portfolio will return an instance of Portfolio, and Project#milestones will return a dataset of Milestone instances, in similar fashion to how ActiveRecord infers class names.

Association definitions are also reflected by the class, e.g.:

>> Project.associations
=> [:portfolio, :milestones]
>> Project.association_reflection(:portfolio)
=> {:kind => :many_to_one, :name => :portfolio, :class_name => "Portfolio"}

The following association kinds are supported:

  • :many_to_one - Foreign key in current model’s table points to associated model’s primary key. Each associated model object can be associated with more than one current model objects. Each current model object can be associated with only one associated model object. Similar to ActiveRecord/DataMapper’s belongs_to.

  • :one_to_many - Foreign key in associated model’s table points to this model’s primary key. Each current model object can be associated with more than one associated model objects. Each associated model object can be associated with only one current model object. Similar to ActiveRecord/DataMapper’s has_many.

  • :many_to_many - A join table is used that has a foreign key that points to this model’s primary key and a foreign key that points to the associated model’s primary key. Each current model object can be associated with many associated model objects, and each associated model object can be associated with many current model objects. Similar to ActiveRecord/DataMapper’s has_and_belongs_to_many.

Associations can be defined by either using the associate method, or by calling one of the three methods: many_to_one, one_to_many, many_to_many. Sequel::Model also provides aliases for these methods that conform to ActiveRecord conventions: belongs_to, has_many, has_and_belongs_to_many. For example, the following two statements are equivalent:

associate :one_to_many, :attributes
one_to_many :attributes

Instance Method Summary collapse

Instance Method Details

#all_association_reflectionsObject

Array of all association reflections



57
58
59
# File 'lib/sequel_model/associations.rb', line 57

def all_association_reflections
  association_reflections.values
end

#associate(type, name, opts = {}, &block) ⇒ Object

Associates a related model with the current model. The following types are supported:

  • :many_to_one - Foreign key in current model’s table points to associated model’s primary key. Each associated model object can be associated with more than one current model objects. Each current model object can be associated with only one associated model object. Similar to ActiveRecord/DataMapper’s belongs_to.

  • :one_to_many - Foreign key in associated model’s table points to this model’s primary key. Each current model object can be associated with more than one associated model objects. Each associated model object can be associated with only one current model object. Similar to ActiveRecord/DataMapper’s has_many.

  • :many_to_many - A join table is used that has a foreign key that points to this model’s primary key and a foreign key that points to the associated model’s primary key. Each current model object can be associated with many associated model objects, and each associated model object can be associated with many current model objects. Similar to ActiveRecord/DataMapper’s has_and_belongs_to_many.

The following options can be supplied:

  • *ALL types*:

    • :class_name - The name of the associated class as a string. If not given, uses the association’s name, which is camelized (and singularized if type is :one,many_to_many)

    • :class - The associated class itself. Simpler than using :class_name, but can’t be used always due to dependencies not being loaded.

  • :many_to_one:

    • :key - foreign_key in current model’s table that references associated model’s primary key, as a symbol. Defaults to :“#name_id”.

  • :one_to_many:

    • :key - foreign key in associated model’s table that references current model’s primary key, as a symbol. Defaults to :“#Sequel::Model::Associations.selfself.nameself.name.underscore_id”.

    • :order - the column by which to order the association dataset.

    • :cache - set to true to cache and return an array of objects instead of a dataset.

  • :many_to_many:

    • :join_table - name of table that includes the foreign keys to both the current model and the associated model, as a symbol. Defaults to the name of current model and name of associated model, pluralized, underscored, sorted, and joined with ‘_’.

    • :left_key - foreign key in join table that points to current model’s primary key, as a symbol.

    • :right_key - foreign key in join table that points to associated model’s primary key, as a symbol.

    • :order - the column by which to order the association dataset.

    • :cache - set to true to cache and return an array of objects instead of a dataset.

Raises:

  • (ArgumentError)


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/sequel_model/associations.rb', line 109

def associate(type, name, opts = {}, &block)
  # check arguments
  raise ArgumentError unless [:many_to_one, :one_to_many, :many_to_many].include?(type) && Symbol === name

  # deprecation
  if opts[:from]
    STDERR << "The :from option is deprecated, please use the :class option instead.\r\n"
    opts[:class] = opts[:from]
  end

  # prepare options
  opts[:class_name] ||= opts[:class].name if opts[:class]
  opts = association_reflections[name] = opts.merge(:type => type, :name => name, :block => block)

  send(:"def_#{type}", name, opts)
end

#association_reflection(name) ⇒ Object

The association reflection hash for the association of the given name.



127
128
129
# File 'lib/sequel_model/associations.rb', line 127

def association_reflection(name)
  association_reflections[name]
end

#associationsObject

Array of association name symbols



132
133
134
# File 'lib/sequel_model/associations.rb', line 132

def associations
  association_reflections.keys
end

#many_to_many(*args, &block) ⇒ Object Also known as: has_and_belongs_to_many

Shortcut for adding a many_to_many association, see associate



155
156
157
# File 'lib/sequel_model/associations.rb', line 155

def many_to_many(*args, &block)
  associate(:many_to_many, *args, &block)
end

#many_to_one(*args, &block) ⇒ Object Also known as: belongs_to

Shortcut for adding a many_to_one association, see associate



137
138
139
# File 'lib/sequel_model/associations.rb', line 137

def many_to_one(*args, &block)
  associate(:many_to_one, *args, &block)
end

#one_to_many(*args, &block) ⇒ Object Also known as: has_many

Shortcut for adding a one_to_many association, see associate



143
144
145
# File 'lib/sequel_model/associations.rb', line 143

def one_to_many(*args, &block)
  associate(:one_to_many, *args, &block)
end

#one_to_one(*args, &block) ⇒ Object

deprecated, please use many_to_one instead



149
150
151
152
# File 'lib/sequel_model/associations.rb', line 149

def one_to_one(*args, &block)
  STDERR << "one_to_one relation definitions are deprecated, please use many_to_one instead.\r\n"
  many_to_one(*args, &block)
end