method_docs ( Alzabo::MethodDocs->new ( name => $name, group => 'Methods that follow a linking table', description => "a row cursor of related rows from the " . $fk_2->table_to->name . " table, " . "via the " . $fk->table_to->name . " linking table", spec => 'same as Alzabo::Runtime::Table->rows_where', ) ); } sub make_lookup_columns_methods { my $self = shift; my $fk = shift; return if $fk->is_one_to_many; # Make sure the relationship is to the foreign table's primary key my @to = $fk->columns_to; return unless ( ( scalar grep { $_->is_primary_key } @to ) == @to && ( $fk->table_to->primary_key_size == @to ) ); foreach ( sort { $a->name cmp $b->name } $fk->table_to->columns ) { next if $_->is_primary_key; my $col_name = $_->name; my $name = $self->_make_method ( type => 'lookup_columns', class => $self->{row_class}, returns => 'scalar value of column', code => sub { my $self = shift; my $row = $self->rows_by_foreign_key( foreign_key => $fk, @_ ); return unless $row; return $row->select($col_name) }, foreign_key => $fk, column => $_, ) or next; $self->{row_class}->add_method_docs ( Alzabo::MethodDocs->new ( name => $name, group => 'Methods that follow a lookup table', description => "returns the value of " . (join '.', $fk->table_to->name, $col_name) . " for the given row by following the foreign key relationship", spec => 'same as Alzabo::Runtime::Table->rows_where', ) ); } } sub make_hooks { my $self = shift; my $table = shift; my $type = shift; my $class = $type eq 'insert' ? $self->{table_class} : $self->{row_class}; my $pre = "pre_$type"; my $post = "post_$type"; return unless $class->can($pre) || $class->can($post); my $method = join '::', $class, $type; { no strict 'refs'; return if *{$method}{CODE}; } print STDERR "Making $type hooks method $class\->$type\n" if Alzabo::Debug::METHODMAKER; my $meth = "make_$type\_hooks"; $self->$meth($table); } sub make_insert_hooks { my $self = shift; my $code = ''; $code .= " return \$s->schema->run_in_transaction( sub {\n"; $code .= " my \$new;\n"; $code .= " \$s->pre_insert(\\\%p);\n" if $self->{table_class}->can('pre_insert'); $code .= " \$new = \$s->SUPER::insert(\%p);\n"; $code .= " \$s->post_insert({\%p, row => \$new});\n" if $self->{table_class}->can('post_insert'); $code .= " return \$new;\n"; $code .= " } );\n"; eval <<"EOF"; {