Abstract Class Misago\ActiveRecord\Associations

Model object relationships.

Relationships

belongs_to

Represents a one-to-one relationship, in the point of view of the child. The counterpart is either a has_one or has_many relationship (see below).

Example:

A comment belongs to a blog post.

class Post Extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::has_many('comments');
  }
}

class Comment Extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::belongs_to('post');
  }
}

$comment    = new Comment(456);
$post_id    = $comment->post->id;
$post_title = $comment->post->title; 

Options for belongs to

has_one

Represents a one-to-one relationship, in the point of view of the parent. The counterpart is a belongs_to relationship.

The difference with a belongs_to relationship, is where the foreign key is located: in this model for a belongs_to relationship; in the related model for a has_one relationship.

Example:

An order has one invoice.

class Order extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::has_one('invoice');
  }
}

class Invoice extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::belongs_to('order');
  }
}

$order = new Order(456);
$invoice_id = $order->invoice->id; 

Options for has_one

has_many

Represents a one-to-many relationship, in the point of view of the parent. The counterpart is a belongs_to relationship.

Example:

A post may have many tags.

class Post Extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::has_many('tags');
  }
}

class Tag Extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::belongs_to('post');
  }
}

$post = new Post(123);
foreach($post->tags as $tag) {
  echo $tag->name.", ";
} 

Options for has_many

:through

Declares a has_many relationship, but through a join model.

[TODO]

has_and_belongs_to_many

Declares a many-to-many relationship, using a join table with no associated model nor primary key.

Example:

A programmer may have many projects, and a project may belong to (or have) many programmers.

class Programmer extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::has_and_belongs_to_many('projects');
  }
}

class Project extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::has_and_belongs_to_many('programmers');
  }
} 

Options for has_and_belongs_to_many

Join table

An HABTM relationship requires the existence of a join table with no primary key but containing foreign keys of both models.

The join table name is made by comparing sizes of both models' name, using the < operator. The smaller one before. For our previous example, the projects-programmers relationship, the join table name would be programmers_projects.

In fact previous example requires the following table and fields:

programmers_projects
--------------------
programmer_id
project_id 

Auto-generated methods and attributes

Singular associations (one-to-one)

Declaring a belongs_to or has_one association generates the following attributes and methods (where other is the name of the relation, for instance invoice, post, etc).

Plural associations (one-to-many / many-to-many)

Declaring a has_many or has_and_belongs_to_many association generates the following attributes and methods (where others is the name of the relation, for instance posts, comments, etc).

See Misago\ActiveRecord\Collection for details.

Dependent relations

You may want to delete, destroy or nullify dependent relations when you delete a record. For instance when deleting a blog post, you better delete all associated comments and tags.

By default this is not activated. You have to define it.

class Post extends Misago\ActiveRecord\Base
{
  static function __constructStatic()
  {
    static::has_to_many('projects', array('dependent' => 'destroy_all'));
    static::has_to_many('comments', array('dependent' => 'delete_all'));
  }
} 

Depending on the type of relation, you will have access to different dependent actions:

belongs_to

has_one

has_many

Eager Loading (include)

Permits to limitate repetitive requests of relationships' data by requesting it all at once.

Let's say you want the list of tags for each posts on a blog index page. That would require as many requests as there are posts to be displayed. Thus for 100 posts there would be 101 requests: 1 for the list of posts, and 100 for loading the list of tags for each post.

Of course it's even badder if you also want, say, the list of authors, the list of comments, and more : you would add 100 requests each time! That's quite some SQL overhead, and can be dreadful.

With eager loading, such requests will be reduced to one for each relationship. Our previous example that required 101 requests, would now be reduced to just 2 requests. Which is better.

Example:

Only 3 SQL requests will be issued (instead of 301):

$posts = Post::find(':all', array(
  'limit'   => 100,
  'order'   => 'created_at desc',
  'include' => 'tags, authors',
));
foreach($posts as $post)
{
  print_r($post->tags);
  print_r($post->authors);
} 

FIXME: handle others.build, etc. methods for HABTM relationships. IMPROVE: has_many options: counter_sql, finder_sql IMPROVE: HABTM options: counter_sql, finder_sql, insert_sql, delete_sql TODO: Implement has_many/has_one :throught association.

Inheritence

Extends:
Record

Methods

Public static methods

association($assoc)

Returns an association's configuration. Returns null if no such association exists.

association_names()

Returns the list of associations.

build_join_for($association, $type="inner")

Creates a SQL join fragment for a given association (related to this).

  • $association - the association to build the SQL join fragment with.
  • $type - inner, outer, left, left outer, etc.

has_association($assoc)

Protected static methods

belongs_to($name, $options=array())

eager_loading($records, $includes)

habtm($name, $options=array())

Shortcut for has_and_belongs_to_many.

has_and_belongs_to_many($name, $options=array())

TODO: add 'autosave' and 'validate' options for HABTM relationships.

has_many($name, $options=array())

TODO: add 'autosave' and 'validate' options for has_many relationships.

has_one($name, $options=array())

TODO: add 'autosave' and 'validate' options for has_one relationships.