Skip to content

add support for row methods to the active_column #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions lib/HTML/FormHandler/TraitFor/Model/DBIC.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use Moose::Role;
use Carp;
use DBIx::Class::ResultClass::HashRefInflator;
use DBIx::Class::ResultSet::RecursiveUpdate;
use Scalar::Util ('blessed');
use Scalar::Util ('blessed', 'looks_like_number');

our $VERSION = '0.26';

Expand Down Expand Up @@ -162,6 +162,9 @@ This allows setting the name of the active column globally if
your tables are consistantly named (all lookup tables have the same
column name to indicate they are active), or on a per-field basis.

The active column can be a row method rather an actual result source column,
but that requires checking each row individually *after* fetching all rows.

The column to use for sorting the list is specified with "sort_column".
The currently selected values in a Multiple list are grouped at the top
(by the Multiple field class).
Expand Down Expand Up @@ -373,8 +376,10 @@ sub lookup_options {
unless ( $source->has_column($label_column) ||
$source->result_class->can($label_column) );

my $active_col = $self->active_column || $field->active_column;
$active_col = '' unless $source->has_column($active_col);
my $active_check = $self->active_column || $field->active_column;
my $active_check_method = $source->result_class->can($active_check) && ! $source->has_column($active_check);
$active_check = '' unless $source->result_class->can($active_check) || $source->has_column($active_check);

my $sort_col = $field->sort_column;
my ($primary_key) = $source->primary_columns;

Expand All @@ -385,10 +390,10 @@ sub lookup_options {
$sort_col = $source->has_column($label_column) ? $label_column : $primary_key;
}

# If there's an active column, only select active OR items already selected
# If there's an active check, and it's a column, only select active OR items already selected
my $criteria = {};
if ($active_col) {
my @or = ( $active_col => 1 );
if ($active_check && ! $active_check_method ) {
my @or = ( $active_check => 1 );

# But also include any existing non-active
push @or, ( "$primary_key" => $field->init_value )
Expand All @@ -401,10 +406,26 @@ sub lookup_options {
$self->schema->resultset( $source->source_name )
->search( $criteria, { order_by => $sort_col } )->all;
my @options;

foreach my $row (@rows) {

# The active check is not a real column, so we must weed rows using the row's method
if( $active_check && $active_check_method ) {
my $is_pk;

if( $self->item && defined $field->init_value ) {
$is_pk = looks_like_number($row->$primary_key) ?
$row->$primary_key == $field->init_value :
$row->$primary_key eq $field->init_value;
}


# skip if not PK nor active
next if ! $row->$active_check && ! $is_pk;
}
my $label = $row->$label_column;
next unless defined $label; # this means there's an invalid value
push @options, $row->id, $active_col && !$row->$active_col ? "[ $label ]" : "$label";
push @options, $row->id, $active_check && !$row->$active_check ? "[ $label ]" : "$label";
}
return \@options;
}
Expand Down
24 changes: 23 additions & 1 deletion t/active_column.t
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,35 @@ use BookDB::Schema;
active_column => 'is_active',
);
}
{
package MyApp::Form::Test2;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler::Model::DBIC';

has '+item_class' => ( default => 'Book' );
has_field 'title' => (
type => 'Text',
required => 1,
);

# has_many relationship pointing to mapping table
has_field 'genres' => (
type => 'Multiple',
label_column => 'name',
active_column => 'check_active',
);
}

my $schema = BookDB::Schema->connect('dbi:SQLite:t/db/book.db');
my $form = MyApp::Form::Test->new( schema => $schema );
my $form2 = MyApp::Form::Test2->new( schema => $schema );

ok( $form );
ok( $form2 );

is( $form->field('genres')->num_options, 3, 'right number of options with column' );
is( $form2->field('genres')->num_options, 3, 'right number of options with method' );

is( $form->field('genres')->num_options, 3, 'right number of options' );

done_testing;

3 changes: 3 additions & 0 deletions t/lib/BookDB/Schema/Result/Genre.pm
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@ BookDB::Schema::Result::Genre->many_to_many(
books => 'books_genres', 'book'
);

sub check_active {
$_[0]->is_active;
}

1;