DBIx::DataModel::Meta::Association(3p)

NAME
DBIx::DataModel::Meta::Association - meta-information about an association

SYNOPSIS
  # create the assoc.; best called through $meta_schema->define_association(..)
  my $association = new (
    schema => $meta_schema,
    A      => {
      table        => $meta_table_instance,
      role         => $role_name,         # optional
      multiplicity => $multiplicity_spec, # ex. "1..*"
      join_cols    => [$col1, ...]        # optional
    },
    B      => $B_association_end, # same structure as 'A'
    name   => $association_name, #optional
    kind   => $kind, # one of : Association, Aggregation, Composition
  );

  # example
  my $path = $association->path_AB;
  #

DESCRIPTION
An instance of this class represents a UML association between two instances of DBIx::DataModel::Meta::Source::Table.

The association also creates instances of DBIx::DataModel::Meta::Path for representing the directional paths between those sources. Perl methods are created within the DBIx::DataModel::Meta::Path class, so Perl symbol tables are not touched by the present class.

PUBLIC METHODS

  new
Constructor method. Normally this will be called indirectly through

  $meta_schema->define_association(%args)

because the "define_association" in DBIx::DataModel::Meta::Schema method automatically adds its own invocant (the $meta_schema) into %args.

Named arguments to new() are :

schema
    An instance of DBIx::DataModel::Meta::Schema.

A   A description of the first association end, which is composed of

    table
        An instance of DBIx::DataModel::Meta::Source::Table.

    role
        The role name of that source within the association. A Perl method of the same name will be defined in the remote source (the other end of the association). Besides, the role name is also used when building joins through

          $schema->join(qw/FirstTable role1 role2 .../)

        One of the role names in the association can be anonymous (undef), but not both. If anonymous, there will be no Perl method and no possibility to join in that direction, so it defines a unidirectional association.

    multiplicity
        The multiplicity specification, i.e. the minimum and maximum number of occurrences of that association end, for any given instance of the other end (if not clear, see UML textbooks).

        The multiplicity can be expressed either as an arrayref "[$min, $max]", or as a string "$min..$max". The $max can be '*' or 'n', which is interpreted as the maximum integer value. If expressed as a string, a mere '*' is interpreted as '0..*', and a mere '1' is interpreted as '1..1'.

    join_cols
        An arrayref of columns that participate in the database join, for this side of the association. The full database join will be built by creating a "LEFT|INNER JOIN ... ON .." clause in which the left-hand and right-hand sides of the "ON" subclause come from the "join_cols" of both association ends.

        This argument is optional: if absent, it will be filled by default by taking the primary key of the table with minimum multiplicity 1, for both sides of the association.

        If the association is many-to-many (i.e. if the maximum multiplicity is greater than 1 on both sides), then "join_cols" takes a special meaning : it no longer represents database columns, but rather represents two role names (in the sense just defined above) to follow for reaching the remote end of the association. Therefore "join_cols" must contain exactly 2 items in that case : the path to the intermediate table, and the path from the intermediate table to the remote end. Here is again the example from "SYNOPSIS" in DBIx::DataModel :

          My::Schema->define_association(
            kind => 'Association',
            A    => {
              table        => My::Schema::Department->metadm,
              role         => 'departments',
              multiplicity => '*',
              join_cols    => [qw/activities department/],
            },
            B    => {
              table        => My::Schema::Employee->metadm,
              role         => 'employees',
              multiplicity => '*',
              join_cols    => [qw/activities employee/],
            },
          );

B   A description of the second association end, following exactly the same principles as for the 'A' end.

name
    Optional name for the association (otherwise an implicit name will be built by default from the concatenation of the role names).

kind
    A string describing the association kind, i.e. one of : "Association", "Aggregation" or "Composition".

    Special behaviour is attached to the kind "Composition" :

    •   the multiplicity must be 1-to-n or 1-to-0..1

    •   the 'B' end of the association (the "component" part) must not be component of another association (it can only be component of one single composite table).

    •   this association can be used for auto-expanding the composite object (i.e. automatically fetching all component parts from the database) -- see "expand" in DBIx::DataModel::Source and "auto_expand" in DBIx::DataModel::Source

    •   this association can be used for cascaded inserts like

          $source->insert({
            column1 => $val1,
            ...
            $component_name1 => [{$sub_object1}, ...],
            ...
           })

        see "insert" in DBIx::DataModel::Source

  schema
returns the $meta_schema to which this association belongs

  A
hashref decribing the 'A' end of the association

  B
hashref decribing the 'B' end of the association

  path_AB
An instance of DBIx::DataModel::Meta::Path for the path from "A" to "B" within this association (if any).

  path_BA
An instance of DBIx::DataModel::Meta::Path for the path from "B" to "A" within this association (if any).

  name
The association name.

  kind
The association kind.

PRIVATE METHODS

  _parse_multiplicity
For multiplicities given as strings, parse into an arrayref "[$min, $max]", including the rules for shorthands '*' and '1', as described above.

  _install_path
Implementation for regular associations (1-to-n or 1-to-1): create a DBIx::DataModel::Meta::Path object from one side to the other.

  _install_many_to_many
Implementation for many-to-many associations : just create navigation methods from one side to the other, relying on pre-existing paths through the intermediate table.

  _check_composition
Checks that special conditions on compositions (described above) are fullfilled.