interface)
If you fancy playing around with DBIx::Class from scratch, then read the docs
-for ::Table and ::Relationship,
+for DBIx::Class::Table, ::Row, ::Schema, ::DB and ::Relationship,
use base qw/DBIx::Class/;
__PACKAGE__->load_components(qw/Core DB/);
ColumnCase
HasMany
HasA
+ MightHave
LazyLoading
AutoUpdate
TempColumns
--- /dev/null
+package DBIx::Class::CDBICompat::MightHave;
+
+use strict;
+use warnings;
+
+sub might_have {
+ my ($class, $rel, $f_class, @columns) = @_;
+ if (ref $columns[0] || !defined $columns[0]) {
+ return $class->NEXT::might_have($rel, $f_class, @columns);
+ } else {
+ return $class->NEXT::might_have($rel, $f_class, undef,
+ { proxy => \@columns });
+ }
+}
+
+1;
package MyDB;
use base qw/DBIx::Class/;
- __PACKAGE__->load_components('Core');
+ __PACKAGE__->load_components('DB');
__PACKAGE__->connection('dbi:...', 'user', 'pass', \%attrs);
package MyDB::MyTable;
use base qw/MyDB/;
+ __PACKAGE__->load_components('Core');
...
model. It allows your to set up relationships, and to perform joins
on searches.
+This POD details only the convenience methods for setting up standard
+relationship types. For more information see ::Relationship::Base
+
=head1 METHODS
+All convenience methods take a signature of the following format -
+
+ __PACKAGE__>method_name('relname', 'Foreign::Class', $join?, $attrs?);
+
+
+
=over 4
+=item has_one
+
+ my $f_obj = $obj->relname;
+
+Creates a one-one relationship with another class; defaults to PK-PK for
+the join condition unless a condition is specified.
+
+=item might_have
+
+ my $f_obj = $obj->relname;
+
+Creates an optional one-one relationship with another class; defaults to PK-PK
+for the join condition unless a condition is specified.
+
+=item has_many
+
+ my @f_obj = $obj->relname($cond?, $attrs?);
+ my $f_result_set = $obj->relname($cond?, $attrs?);
+
+ $obj->add_to_relname(\%col_data);
+
+Creates a one-many relationship with another class;
+
+=item belongs_to
+
+ my $f_obj = $obj->relname;
+
+ $obj->relname($new_f_obj);
+
+Creates a relationship where we store the foreign class' PK; if $join is a
+column name instead of a condition that is assumed to be the FK, if not
+has_many assumes the FK is the relname is that is a column on the current
+class.
+
=cut
1;
=over 4
+=item add_relationship
+
+ __PACKAGE__->add_relationship('relname', 'Foreign::Class', $cond, $attrs);
+
+The condition needs to be an SQL::Abstract-style representation of the
+join between the tables - for example if you're creating a rel from Foo to Bar
+
+ { 'foreign.foo_id' => 'self.id' }
+
+will result in a JOIN clause like
+
+ foo me JOIN bar bar ON bar.foo_id = me.id
+
=cut
sub add_relationship {
return $self->NEXT::ACTUAL::_cond_value($attrs, $key, $value)
}
+=item search_related
+
+ My::Table->search_related('relname', $cond, $attrs);
+
+=cut
+
sub search_related {
my $self = shift;
return $self->_query_related('search', @_);
}
+=item count_related
+
+ My::Table->count_related('relname', $cond, $attrs);
+
+=cut
+
sub count_related {
my $self = shift;
return $self->_query_related('count', @_);
)->$meth($query, $attrs);
}
+=item create_related
+
+ My::Table->create_related('relname', \%col_data);
+
+=cut
+
sub create_related {
my $class = shift;
return $class->new_related(@_)->insert;
}
+=item new_related
+
+ My::Table->new_related('relname', \%col_data);
+
+=cut
+
sub new_related {
my ($self, $rel, $values, $attrs) = @_;
$self->throw( "Can't call new_related as class method" )
return $self->resolve_class($rel_obj->{class})->new(\%fields);
}
+=item find_related
+
+ My::Table->find_related('relname', @pri_vals | \%pri_vals);
+
+=cut
+
sub find_related {
my $self = shift;
my $rel = shift;
return $self->resolve_class($rel_obj->{class})->find($query);
}
+=item find_or_create_related
+
+ My::Table->find_or_create_related('relname', \%col_data);
+
+=cut
+
sub find_or_create_related {
my $self = shift;
return $self->find_related(@_) || $self->create_related(@_);
}
+=item set_from_related
+
+ My::Table->set_from_related('relname', $rel_obj);
+
+=cut
+
sub set_from_related {
my ($self, $rel, $f_obj) = @_;
my $rel_obj = $self->_relationships->{$rel};
return 1;
}
+=item update_from_related
+
+ My::Table->update_from_related('relname', $rel_obj);
+
+=cut
+
sub update_from_related {
my $self = shift;
$self->set_from_related(@_);
$self->update;
}
+=item delete_related
+
+ My::Table->delete_related('relname', $cond, $attrs);
+
+=cut
+
sub delete_related {
my $self = shift;
return $self->search_related(@_)->delete;
return 1;
}
+=head1 AUTHORS
+
+Alexander Hartmaier <Alexander.Hartmaier@t-systems.at>
+
+Matt S. Trout <mst@shadowcatsystems.co.uk>
+
+=cut
+
1;
my %rels = %{ $self->_relationships };
my @cascade = grep { $rels{$_}{attrs}{cascade_delete} } keys %rels;
foreach my $rel (@cascade) {
- $_->delete for $self->search_related($rel);
+ $self->search_related($rel)->delete;
}
return $ret;
}
}
sub _has_one {
- my ($class, $join_type, $rel, $f_class, @columns) = @_;
- my $cond;
- if (ref $columns[0]) {
- $cond = shift @columns;
- } else {
+ my ($class, $join_type, $rel, $f_class, $cond, $attrs) = @_;
+ unless ($cond) {
my ($pri, $too_many) = keys %{ $class->_primaries };
$class->throw( "might_have/has_one can only infer join for a single primary key; ${class} has more" )
if $too_many;
$class->throw( "might_have/has_one can only infer join for a single primary key; ${f_class} has more" )
if $too_many;
}
- $cond = { "foreign.${f_key}" => "self.${pri}" },
+ $cond = { "foreign.${f_key}" => "self.${pri}" };
}
- shift(@columns) unless defined $columns[0]; # Explicit empty condition
- my %attrs;
- if (ref $columns[0] eq 'HASH') {
- %attrs = %{shift @columns};
- }
- shift(@columns) unless defined $columns[0]; # Explicit empty attrs
$class->add_relationship($rel, $f_class,
$cond,
- { accessor => 'single', (@columns ? (proxy => \@columns) : ()),
+ { accessor => 'single',
cascade_update => 1, cascade_delete => 1,
($join_type ? ('join_type' => $join_type) : ()),
- %attrs });
+ %{$attrs || {}} });
1;
}
DBICTest::Schema::CD->has_many(tracks => 'DBICTest::Schema::Track');
DBICTest::Schema::CD->has_many(tags => 'DBICTest::Schema::Tag');
-DBICTest::Schema::CD->might_have(liner_notes => 'DBICTest::Schema::LinerNotes' => qw/notes/);
+DBICTest::Schema::CD->might_have(liner_notes => 'DBICTest::Schema::LinerNotes',
+ undef, { proxy => [ qw/notes/ ] });
DBICTest::Schema::SelfRefAlias->belongs_to(
self_ref => 'DBICTest::Schema::SelfRef');