Clinton Wolfe
and 1 contributors

NAME

Class::ReluctantORM::Relationship::HasManyMany

SYNOPSIS

  # Add many-to-many relationships to a ReluctantORM Class

  # May use has_many if you provide join_table
  Pirate->has_many(
                   class       => 'Booty'
                   join_table => 'booties2pirates',
                  );
  Pirate->has_many_many(
                        class       => 'Booty'
                        method_name => 'booties',
                   # New in 0.4: multi-column keys allowed via arrayrefs
                        local_key   => 'pirate_id',
                        remote_key  => 'booty_id',
                   # New in 0.4: keys can have different names in the join table
                        join_local_key   => 'pirate_id',
                        join_remote_key  => 'booty_id',
                        join_table  => 'booties2pirates',
                        join_schema => 'caribbean',
                );

  # Now you have:
  $booties_collection  = $pirate->booties();

  # New in 0.4: in array context, implicitly do $booties_collection->all_items
  @loot = $pirate->booties();

  # Fetchers defined automatically
  $pirate   = Pirate->fetch_with_booties($pirate_id);
  @bipeds   = Pirate->fetch_by_leg_count_with_booties(2);

  # Get info about the relationship
  $rel = Pirate->relationships('booties');
  $str = $rel->type();                 # 'has_many_many';
  $str = $rel->linked_class();         # 'Booty';
  $str = $rel->linking_class();        # 'Pirate';
  @fields = $rel->local_key_fields();  # fields in Pirate that link to join table
  @fields = $rel->remote_key_fields(); # fields in Booty that link to join table

  $int = $rel->join_depth();           # 2

  # Class::ReluctantORM::SQL integration
  @sql_cols = $rel->additional_output_sql_columns();
  @cols     = $rel->local_key_sql_columns();
  @cols     = $rel->remote_key_sql_columns();
  @empty    = $rel->join_local_key_sql_columns();
  @empty    = $rel->join_remote_key_sql_columns();

DESCRIPTION

CREATING A RELATIONSHIP

$tb_class->has_many(class => 'OtherClass', join_table => 'join_table', ....);

$tb_class->has_many_many(class => 'OtherClass', join_table => 'join table', ...);

Initiates a many-to-many relationship between two classes/tables. Results are handled with assistance of a simple container class, Class::ReluctantORM::Collection::ManyMany (documented below in this file).

An accessor will be created named other_classes (or method_name). Note that this should be plural for readability. The accessor will return a Collection object.

Additionally, a new constructor is created, named $class->fetch_with_METHOD. This constructor has the special feature that it performs an outer join and prepopulates the Collection. Thus, Pirate->fetch_with_booties(23) is only one DB query.

Finally, additional constructors named $class->fetch_by_ATTRIBUTE_with_METHOD will also be available via AUTOLOAD.

Obtaining the Collection object does NOT result in trips to the database. Operations on the Collection object DO require trips to the database.

Note that a many-to-many relationship does not imply a reciprocal has_many_many relationship going the other way. It's OK to set that up manually, though.

The first form is an alias for the second form. Some users find it more readable. That alias is actually provided by the HasMany module.

In the first form, a relationship is setup to OtherClass using defaults, described below.

In the second form, options are made explicit:

class (required)

The linked class. This is the class on the remote end of the many-to-many.

join_table (required)

The name of the join table in the database.

join_schema (optional)

The schema of the join table if different than the local class. Default: $tb_class->schema_name().

method_name (optional)

The name of the method that will be used to access the relationship. This is also the name for the relationship, which you can pass to $tb_class->relationships. Default is the lower-cased and pluralized OtherClass. For example, if you say Pirate->has_many_many(class => 'Booty', ...), you'll get $pirate->booties(). Pluralization is performed using Lingua.

local_key (optional string or arrayref)

Name or names of columns in the local table acting as keys in the link between the local table and the join table. Defaults to $tb_class->primary_key_columns().

remote_key (optional string or arrayref)

Name or names of columns in the remote table acting as keys in the link between the remote table and the join table. Defaults to OtherClass->primary_key_columns().

join_local_key (optional string or arrayref)

Name or names of columns in the join table acting as keys in the link between the join table and the local table. Defaults to $tb_class->primary_key_columns().

join_remote_key (optional string or arrayref)

Name or names of columns in the join table acting as keys in the link between the join table and the remote table. Defaults to OtherClass->primary_key_columns().

join_extra_columns (optional arrayref)

Extra columns from the join table that will be fetched.

$str = $rel->type();

Returns 'has_many_many'.

$int = $rel->join_depth();

Returns 2.

$str = $rel->join_type();

Returns 'LEFT OUTER'.

This is the type of the first of the two joins - from the base table to the join table. The next join, from the join table to the remote table, is always an INNER.

$bool = $rel->is_has_many_many();

Returns true.

$int = $rel->lower_multiplicity()

Returns 0.

$int = $rel->upper_multiplicity()

Returns undef.