The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 134
LICENSE 44
MANIFEST 334
META.json 411
META.yml 45
Makefile.PL 2029
README 22
SIGNATURE 7041
dist.ini 56
lib/HTML/FormHandler/Generator/DBIC.pm 45
lib/HTML/FormHandler/Model/DBIC/TypeMap.pm 35
lib/HTML/FormHandler/Model/DBIC.pm 46
lib/HTML/FormHandler/TraitFor/DBICFields.pm 35
lib/HTML/FormHandler/TraitFor/Model/DBIC.pm 318326
script/form_generator.pl 45
t/active_column.t 034
t/book.t 312
t/book2pk.t 030
t/datetime.t 75
t/db/book.db --
t/db/bookdb.sql 325
t/db_validate.t 01
t/fif.t 12
t/lib/BookDB/Controller/Author.pm 1080
t/lib/BookDB/Controller/Book.pm 1350
t/lib/BookDB/Controller/Borrower.pm 1090
t/lib/BookDB/Controller/Root.pm 500
t/lib/BookDB/Controller/User.pm 1100
t/lib/BookDB/Form/Book.pm 16
t/lib/BookDB/Form/Book2PK.pm 075
t/lib/BookDB/Form/BookWithOwner.pm 30
t/lib/BookDB/Form/Borrower.pm 20
t/lib/BookDB/Form/BorrowerX.pm 10
t/lib/BookDB/Form/User.pm 10
t/lib/BookDB/Model/DB.pm 360
t/lib/BookDB/Schema/Result/Author.pm 11
t/lib/BookDB/Schema/Result/Book2PK.pm 031
t/lib/BookDB/Schema/Result/Borrower.pm 05
t/lib/BookDB/View/TT.pm 370
t/lib/BookDB/root/book/form.tt 270
t/lib/BookDB/root/book/list.tt 250
t/lib/BookDB/root/book/view.tt 670
t/lib/BookDB/root/borrower/form.tt 140
t/lib/BookDB/root/borrower/list.tt 230
t/lib/BookDB/root/borrower/view.tt 240
t/lib/BookDB/root/scaffold/footer.tt 20
t/lib/BookDB/root/scaffold/header.tt 110
t/lib/BookDB/root/scaffold/header_bg.jpg --
t/lib/BookDB/root/scaffold/nav.tt 80
t/lib/BookDB/root/scaffold/styles.css 1130
t/lib/BookDB/root/user/form.tt 290
t/lib/BookDB/root/user/list.tt 250
t/lib/BookDB/root/user/view.tt 160
t/lib/BookDB/root/widget/checkbox.tt 10
t/lib/BookDB/root/widget/checkbox_group.tt 90
t/lib/BookDB/root/widget/form_end.tt 10
t/lib/BookDB/root/widget/form_start.tt 20
t/lib/BookDB/root/widget/multiple.tt 110
t/lib/BookDB/root/widget/radio.tt 70
t/lib/BookDB/root/widget/select.tt 90
t/lib/BookDB/root/widget/text.tt 30
t/lib/BookDB/root/widget/textarea.tt 40
t/model_dbic.t 01
t/mult_pk.t 04
t/related.t 15
t/release-no-tabs.t 415
t/script/bookdb_schema.pl 170
t/script/bookdb_server.pl 600
t/script/bookdb_test.pl 400
t/unique.t 17
70 files changed (This is a version diff) 1641747
@@ -1,4 +1,37 @@
-0.19 Thu Arp 12, 2012
+0.29
+   Fix tests broken because item is now cleared
+
+0.28
+   Remove unnecessary use of Business::ISBN
+
+0.27
+    Bug: dies with multiple pk table with unique field/column
+
+0.26 Sun Jul 21, 2013
+    Enable use of 'messages' hashref for setting unique message
+
+0.25 Wed Jul 3, 2013
+    Fix bug using result source method for select labels
+    Bump prereq of DBIx::Class::ResultSet::RecursiveUpdate
+
+0.24 Sun May 5, 2013
+    Bump prereq version of DBIC to avoid a regression
+
+0.23 Mon Oct 15, 2012
+    Bump pre-req to non-broken HTML::FormHandler
+
+0.22 Sat Oct 13, 2012
+    Ensure field is active and has a result before checking for errors.
+    Allow using arrayref for sort column
+    Remove Catalyst example (see github formhandler-example)
+
+0.21 Mon May 14, 2012
+    Bump prereq version for HTML::FormHandler
+
+0.20 Mon May 14, 2012
+    Update t/related.t test for compatibility with FH changes
+
+0.19 Thu Apr 12, 2012
     Name conflict between DBICFields and HFH.
         Rename 'include' & 'exclude' in DBICFields.
 0.18 Thu Mar 8, 2012
@@ -1,4 +1,4 @@
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
@@ -12,7 +12,7 @@ b) the "Artistic License"
 
 --- The GNU General Public License, Version 1, February 1989 ---
 
-This software is Copyright (c) 2012 by Gerda Shank.
+This software is Copyright (c) 2013 by Gerda Shank.
 
 This is free software, licensed under:
 
@@ -22,7 +22,7 @@ This is free software, licensed under:
                      Version 1, February 1989
 
  Copyright (C) 1989 Free Software Foundation, Inc.
-                    51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ 51 Franklin St, Suite 500, Boston, MA  02110-1335  USA
 
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
@@ -272,7 +272,7 @@ That's all there is to it!
 
 --- The Artistic License 1.0 ---
 
-This software is Copyright (c) 2012 by Gerda Shank.
+This software is Copyright (c) 2013 by Gerda Shank.
 
 This is free software, licensed under:
 
@@ -16,9 +16,11 @@ lib/HTML/FormHandler/TraitFor/DBICFields.pm
 lib/HTML/FormHandler/TraitFor/Model/DBIC.pm
 script/form_generator.pl
 t/01app.t
+t/active_column.t
 t/author.t
 t/bad_item_id.t
 t/book.t
+t/book2pk.t
 t/datetime.t
 t/db/book.db
 t/db/bookdb.sql
@@ -32,14 +34,10 @@ t/dbic_accessor.t
 t/fif.t
 t/generator.t
 t/lib/BookDB.pm
-t/lib/BookDB/Controller/Author.pm
-t/lib/BookDB/Controller/Book.pm
-t/lib/BookDB/Controller/Borrower.pm
-t/lib/BookDB/Controller/Root.pm
-t/lib/BookDB/Controller/User.pm
 t/lib/BookDB/Form/Author.pm
 t/lib/BookDB/Form/AuthorOld.pm
 t/lib/BookDB/Form/Book.pm
+t/lib/BookDB/Form/Book2PK.pm
 t/lib/BookDB/Form/BookHTML.pm
 t/lib/BookDB/Form/BookM2M.pm
 t/lib/BookDB/Form/BookView.pm
@@ -53,13 +51,13 @@ t/lib/BookDB/Form/Profile.pm
 t/lib/BookDB/Form/Role/BookOwner.pm
 t/lib/BookDB/Form/User.pm
 t/lib/BookDB/Form/Widget/Wrapper/Para.pm
-t/lib/BookDB/Model/DB.pm
 t/lib/BookDB/Schema.pm
 t/lib/BookDB/Schema/Result/Address.pm
 t/lib/BookDB/Schema/Result/Author.pm
 t/lib/BookDB/Schema/Result/AuthorBooks.pm
 t/lib/BookDB/Schema/Result/AuthorOld.pm
 t/lib/BookDB/Schema/Result/Book.pm
+t/lib/BookDB/Schema/Result/Book2PK.pm
 t/lib/BookDB/Schema/Result/BooksGenres.pm
 t/lib/BookDB/Schema/Result/Borrower.pm
 t/lib/BookDB/Schema/Result/Country.pm
@@ -70,30 +68,6 @@ t/lib/BookDB/Schema/Result/License.pm
 t/lib/BookDB/Schema/Result/Options.pm
 t/lib/BookDB/Schema/Result/User.pm
 t/lib/BookDB/Schema/Result/UserEmployer.pm
-t/lib/BookDB/View/TT.pm
-t/lib/BookDB/root/book/form.tt
-t/lib/BookDB/root/book/list.tt
-t/lib/BookDB/root/book/view.tt
-t/lib/BookDB/root/borrower/form.tt
-t/lib/BookDB/root/borrower/list.tt
-t/lib/BookDB/root/borrower/view.tt
-t/lib/BookDB/root/scaffold/footer.tt
-t/lib/BookDB/root/scaffold/header.tt
-t/lib/BookDB/root/scaffold/header_bg.jpg
-t/lib/BookDB/root/scaffold/nav.tt
-t/lib/BookDB/root/scaffold/styles.css
-t/lib/BookDB/root/user/form.tt
-t/lib/BookDB/root/user/list.tt
-t/lib/BookDB/root/user/view.tt
-t/lib/BookDB/root/widget/checkbox.tt
-t/lib/BookDB/root/widget/checkbox_group.tt
-t/lib/BookDB/root/widget/form_end.tt
-t/lib/BookDB/root/widget/form_start.tt
-t/lib/BookDB/root/widget/multiple.tt
-t/lib/BookDB/root/widget/radio.tt
-t/lib/BookDB/root/widget/select.tt
-t/lib/BookDB/root/widget/text.tt
-t/lib/BookDB/root/widget/textarea.tt
 t/model_dbic.t
 t/mult_pk.t
 t/process.t
@@ -103,9 +77,6 @@ t/release-eol.t
 t/release-no-tabs.t
 t/reload_options.t
 t/resultset.t
-t/script/bookdb_schema.pl
-t/script/bookdb_server.pl
-t/script/bookdb_test.pl
 t/unique-composite.t
 t/unique.t
 t/xt/02pod.t
@@ -4,7 +4,7 @@
       "FormHandler Contributors - see HTML::FormHandler"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "Dist::Zilla version 4.300014, CPAN::Meta::Converter version 2.120921",
+   "generated_by" : "Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830",
    "license" : [
       "perl_5"
    ],
@@ -19,11 +19,17 @@
             "ExtUtils::MakeMaker" : "6.30"
          }
       },
+      "develop" : {
+         "requires" : {
+            "Test::More" : "0",
+            "Test::NoTabs" : "0"
+         }
+      },
       "runtime" : {
          "requires" : {
-            "DBIx::Class" : "0",
+            "DBIx::Class" : "0.08250",
             "DBIx::Class::ResultSet::RecursiveUpdate" : "0.25",
-            "HTML::FormHandler" : "0.34001",
+            "HTML::FormHandler" : "0.40016",
             "Moose" : "2.0007",
             "namespace::autoclean" : "0.09"
          }
@@ -33,6 +39,7 @@
             "DateTime::Format::MySQL" : "0",
             "DateTime::Format::SQLite" : "0",
             "DateTime::Format::W3CDTF" : "0",
+            "Test::Exception" : "0",
             "Test::More" : "0.94"
          }
       }
@@ -49,6 +56,6 @@
          "web" : "http://github.com/gshank/html-formhandler-model-dbic"
       }
    },
-   "version" : "0.19"
+   "version" : "0.29"
 }
 
@@ -6,23 +6,24 @@ build_requires:
   DateTime::Format::MySQL: 0
   DateTime::Format::SQLite: 0
   DateTime::Format::W3CDTF: 0
+  Test::Exception: 0
   Test::More: 0.94
 configure_requires:
   ExtUtils::MakeMaker: 6.30
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 4.300014, CPAN::Meta::Converter version 2.120921'
+generated_by: 'Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
   version: 1.4
 name: HTML-FormHandler-Model-DBIC
 requires:
-  DBIx::Class: 0
+  DBIx::Class: 0.08250
   DBIx::Class::ResultSet::RecursiveUpdate: 0.25
-  HTML::FormHandler: 0.34001
+  HTML::FormHandler: 0.40016
   Moose: 2.0007
   namespace::autoclean: 0.09
 resources:
   bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=HTML-FormHandler-Model-DBIC
   repository: git://github.com/gshank/html-formhandler-model-dbic.git
-version: 0.19
+version: 0.29
@@ -11,12 +11,7 @@ use ExtUtils::MakeMaker 6.30;
 my %WriteMakefileArgs = (
   "ABSTRACT" => "base class that holds DBIC model role",
   "AUTHOR" => "FormHandler Contributors - see HTML::FormHandler",
-  "BUILD_REQUIRES" => {
-    "DateTime::Format::MySQL" => 0,
-    "DateTime::Format::SQLite" => 0,
-    "DateTime::Format::W3CDTF" => 0,
-    "Test::More" => "0.94"
-  },
+  "BUILD_REQUIRES" => {},
   "CONFIGURE_REQUIRES" => {
     "ExtUtils::MakeMaker" => "6.30"
   },
@@ -27,30 +22,44 @@ my %WriteMakefileArgs = (
   "LICENSE" => "perl",
   "NAME" => "HTML::FormHandler::Model::DBIC",
   "PREREQ_PM" => {
-    "DBIx::Class" => 0,
+    "DBIx::Class" => "0.08250",
     "DBIx::Class::ResultSet::RecursiveUpdate" => "0.25",
-    "HTML::FormHandler" => "0.34001",
+    "HTML::FormHandler" => "0.40016",
     "Moose" => "2.0007",
     "namespace::autoclean" => "0.09"
   },
-  "VERSION" => "0.19",
+  "TEST_REQUIRES" => {
+    "DateTime::Format::MySQL" => 0,
+    "DateTime::Format::SQLite" => 0,
+    "DateTime::Format::W3CDTF" => 0,
+    "Test::Exception" => 0,
+    "Test::More" => "0.94"
+  },
+  "VERSION" => "0.29",
   "test" => {
     "TESTS" => "t/*.t t/xt/*.t"
   }
 );
 
 
-unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) {
-  my $br = delete $WriteMakefileArgs{BUILD_REQUIRES};
-  my $pp = $WriteMakefileArgs{PREREQ_PM};
-  for my $mod ( keys %$br ) {
-    if ( exists $pp->{$mod} ) {
-      $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod};
-    }
-    else {
-      $pp->{$mod} = $br->{$mod};
-    }
-  }
+my %FallbackPrereqs = (
+  "DBIx::Class" => "0.08250",
+  "DBIx::Class::ResultSet::RecursiveUpdate" => "0.25",
+  "DateTime::Format::MySQL" => 0,
+  "DateTime::Format::SQLite" => 0,
+  "DateTime::Format::W3CDTF" => 0,
+  "HTML::FormHandler" => "0.40016",
+  "Moose" => "2.0007",
+  "Test::Exception" => 0,
+  "Test::More" => "0.94",
+  "namespace::autoclean" => "0.09"
+);
+
+
+unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
+  delete $WriteMakefileArgs{TEST_REQUIRES};
+  delete $WriteMakefileArgs{BUILD_REQUIRES};
+  $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
 }
 
 delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
@@ -1,11 +1,11 @@
 
 
 This archive contains the distribution HTML-FormHandler-Model-DBIC,
-version 0.19:
+version 0.29:
 
   base class that holds DBIC model role
 
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
@@ -1,5 +1,5 @@
 This file contains message digests of all files listed in MANIFEST,
-signed via the Module::Signature module, version 0.68.
+signed via the Module::Signature module, version 0.73.
 
 To verify the content in this distribution, first make sure you have
 Module::Signature installed, then type:
@@ -14,69 +14,67 @@ not run its Makefile.PL or Build.PL.
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA256
 
-SHA1 42d2132809352927592089c248339e5a8bbf0093 Changes
+SHA1 fe21ef57fd8b1966c6725b8b604ffca56d96dd4a Changes
 SHA1 674ec091357ed31599f8081acb61b17054e1650e INSTALL
-SHA1 db5549ef0b451d5723593f2156141e6708484dfd LICENSE
-SHA1 97f1649eea605f33b1d0b77515dce959c107e34e MANIFEST
-SHA1 1449dbe7991a5ee81a42c45a128b7e0b9aefa063 META.json
-SHA1 49d303fa2efd015a05a61d61279ec7e1f561461a META.yml
-SHA1 cad692065e9d195a19a20466c69521ec31206bc0 Makefile.PL
-SHA1 30c519856b7e95a311534d54bfd2c18616c2202b README
+SHA1 967770b7299781100fc6c94a225abbf8f3bce5c3 LICENSE
+SHA1 ce9b8c00e5f9b8abee54abdd1a3f07f2b8277bba MANIFEST
+SHA1 b0b59313a7bacd4764d9a0f4d4c222a6c943b65f META.json
+SHA1 1d8a25710075430e548cd2089b421f6e87ef880c META.yml
+SHA1 4f014b53564cce3862467797b73ec250f2cba0e9 Makefile.PL
+SHA1 de3cfd3346fdea5edfafee42c5e68b12be2948db README
 SHA1 a8d73c860cf746b8a1a74ff351719f9c53a3f560 TODO
-SHA1 4f65cf453de6b0706a44b8a825623f39720d0a9f dist.ini
-SHA1 64205422823081d86b44d9f2e90ebf82e8516c10 lib/HTML/FormHandler/Generator/DBIC.pm
-SHA1 e7fd03cc1457e26b25c3065e0c1798437e29bd81 lib/HTML/FormHandler/Model/DBIC.pm
-SHA1 a4d79e2ccb1e9fdb558977a008c939710ff0580a lib/HTML/FormHandler/Model/DBIC/TypeMap.pm
-SHA1 72ca910a213fca9d73cbb5b066faf44f0a45597e lib/HTML/FormHandler/TraitFor/DBICFields.pm
-SHA1 d4a5bb0d406c0f8229b9678bf3ae56d14c76e672 lib/HTML/FormHandler/TraitFor/Model/DBIC.pm
-SHA1 db8588ea6cdd1ddd37253723e92bf6628c63a395 script/form_generator.pl
+SHA1 5782034a434578ffbef9d558fc6384e373ee127b dist.ini
+SHA1 8c5f1f8e33ceca70f1ed97b718c35a860e4a0a80 lib/HTML/FormHandler/Generator/DBIC.pm
+SHA1 64edeff55f1c5c6f5780519d430f1ce243230714 lib/HTML/FormHandler/Model/DBIC.pm
+SHA1 10f083d614ddd2a2340d7261f86b6c7f6eebf0fb lib/HTML/FormHandler/Model/DBIC/TypeMap.pm
+SHA1 70f6d5fc419cd22c7066867527f84db9bd4e5711 lib/HTML/FormHandler/TraitFor/DBICFields.pm
+SHA1 4b1f634a1bec844a1318205f357f01e5f529bc3b lib/HTML/FormHandler/TraitFor/Model/DBIC.pm
+SHA1 1825d59f01834a02b1e1efdc0b5c5b0ad232c373 script/form_generator.pl
 SHA1 e141c74dbb016fc0b4e2ff548cb113e0e6cbeac9 t/01app.t
+SHA1 c910b1623c4b03c14d280a01d42979e28ec8f102 t/active_column.t
 SHA1 b19a7d514320858a9f58455635c346aa4da663d8 t/author.t
 SHA1 b03b8d035f37e3b2789fa33657b28fa909bd014c t/bad_item_id.t
-SHA1 399dc976c3c4cdc84ed84101363f30c37da127ff t/book.t
-SHA1 87724602fd8b108f56453a5b5be0bb607cdf2ad4 t/datetime.t
-SHA1 0379114c142933c7920fe7f58e0a0e8446d702db t/db/book.db
-SHA1 5cc844898f08f8e4f30a8ca897c41eae01902c0b t/db/bookdb.sql
+SHA1 e05624f03890ccc13b0433864c21af1db0f763c2 t/book.t
+SHA1 cd2214898eb4484fd5d515b85a34c060312a9e2a t/book2pk.t
+SHA1 ffdd1e69a43a80a797d7765146e86dd99f61ae63 t/datetime.t
+SHA1 8953c764134a5357628253d6489c350f0dcd7eb7 t/db/book.db
+SHA1 dc44fb3bb1b947d18d4d3b2b859ac4cd5ae24439 t/db/bookdb.sql
 SHA1 553c4d810e9fc902273195f5661386def69a72f4 t/db_fif.t
 SHA1 2e318f0ec4d69ce9622b31071c73189cbd0d1562 t/db_has_many.t
 SHA1 653c2c4049390afdad5c773a1399c689adc4b7f4 t/db_has_one.t
 SHA1 26a8c60b598eb22e83bdeee7157577e11e62d93b t/db_init_obj.t
 SHA1 2f64d47a773825667cf5d86b33edc540c1385d84 t/db_options.t
-SHA1 3b7450422ca4644db2edfc770654754823c2f304 t/db_validate.t
+SHA1 1bed26a49caf08976e1de8fbd0fec0998d8bbbf7 t/db_validate.t
 SHA1 f53b0d40db8b918eccd29267d7d0f269890b5bfa t/dbic_accessor.t
-SHA1 dd8c16f7e681548f72329080be47fd0f8d464be5 t/fif.t
+SHA1 6cb226a1240bec6c188279b0ed041ddc265c59d4 t/fif.t
 SHA1 6503092531bd4ad63ed835763be21662eaa13c03 t/generator.t
 SHA1 14989b01195d51bfe165bda524799c5ad84919de t/lib/BookDB.pm
-SHA1 db06939e496e5852bc336d58315ffada43c4c231 t/lib/BookDB/Controller/Author.pm
-SHA1 a942881d4fad82aa52035c92f42adc0e87e4c1ee t/lib/BookDB/Controller/Book.pm
-SHA1 5fbb18def9bdd91a6eb25cfe0bc6afa6ccf39ac1 t/lib/BookDB/Controller/Borrower.pm
-SHA1 3dcf72358a973af5d917f63ff6d8f6bca66e9fff t/lib/BookDB/Controller/Root.pm
-SHA1 18dca5ed0286face21bfa0083d16e483d9e72773 t/lib/BookDB/Controller/User.pm
 SHA1 71ed372b5f2cb0040c98b333e242878e3bc917c4 t/lib/BookDB/Form/Author.pm
 SHA1 0d2b18d1c28bbdd9611033ec44648333539e1c1d t/lib/BookDB/Form/AuthorOld.pm
-SHA1 27a5fd4c807fae2bd317ea5145a5b9ba192c2c4c t/lib/BookDB/Form/Book.pm
+SHA1 57ac298e6e3abc17f2bc5e48220c7c1c462a7bb2 t/lib/BookDB/Form/Book.pm
+SHA1 d08154338f45a07137f85d6ae0c7cb54a1ef95ca t/lib/BookDB/Form/Book2PK.pm
 SHA1 b5ce1b76ee76505069efa62d4f201fae7b2d457c t/lib/BookDB/Form/BookHTML.pm
 SHA1 d426249c86ae939b3032846bc82d9ec903c57cc5 t/lib/BookDB/Form/BookM2M.pm
 SHA1 cbe1dd7bcedd279e943e81a4f1bd89e8f6890c7e t/lib/BookDB/Form/BookView.pm
-SHA1 974f56c17967ef8164ad7db2cfeb877c63d0e11c t/lib/BookDB/Form/BookWithOwner.pm
+SHA1 6d1b7df8508891980e7325f16066e451fdb3a45d t/lib/BookDB/Form/BookWithOwner.pm
 SHA1 e945ca281a96165e1b542e87c0e67fc2ec688683 t/lib/BookDB/Form/BookWithOwnerAlt.pm
-SHA1 8cdcd53fa419e062eed4d1ede46250d74cdd74e9 t/lib/BookDB/Form/Borrower.pm
-SHA1 a0df6f6344af5f5b34950f1c03917041df59169f t/lib/BookDB/Form/BorrowerX.pm
+SHA1 55c26211bd5859eb54573158661e6ad913ccad83 t/lib/BookDB/Form/Borrower.pm
+SHA1 b1d89bc3684b26fc4678f57580c9d396c08449ba t/lib/BookDB/Form/BorrowerX.pm
 SHA1 b201ee288c67a44751dc48832dfb0ff405239246 t/lib/BookDB/Form/Field/AltText.pm
 SHA1 19e2bf714db84a6120e38357c6b5b5c00c2fe60b t/lib/BookDB/Form/Field/Book.pm
 SHA1 15f91756fee51fe615ff7b0c82f37546dbfccf61 t/lib/BookDB/Form/Profile.pm
 SHA1 b2d3f780148e70207f312436f11bed1ec024e26f t/lib/BookDB/Form/Role/BookOwner.pm
-SHA1 7d7d2599830bab598c846e9c93d43840113a2a5b t/lib/BookDB/Form/User.pm
+SHA1 476d556d4fcb2acfdf013901443951634edf24fc t/lib/BookDB/Form/User.pm
 SHA1 6f59b959717ea61499038f05f21999650edb5241 t/lib/BookDB/Form/Widget/Wrapper/Para.pm
-SHA1 2c0a14f1bf39278448bf2e210a7d7cadfbfb3109 t/lib/BookDB/Model/DB.pm
 SHA1 a6ee6f269e6024d675d22c40b0a5bb4aa859ca40 t/lib/BookDB/Schema.pm
 SHA1 4856e496246686ef913209a49a4dc57904dce5a7 t/lib/BookDB/Schema/Result/Address.pm
-SHA1 9e0c5e7d538cd74be568a2eaead6d6c347b11e0f t/lib/BookDB/Schema/Result/Author.pm
+SHA1 742e87180a2599893a806f2d03cc57f5f705088e t/lib/BookDB/Schema/Result/Author.pm
 SHA1 66660fb22bcb833e82609ac33ba4183261be2f66 t/lib/BookDB/Schema/Result/AuthorBooks.pm
 SHA1 47bc39eb211a3e8be2ec2c7b5281dddc001ca13f t/lib/BookDB/Schema/Result/AuthorOld.pm
 SHA1 f7e3a768098f9ee0b197e0b2276b90cabfef6c83 t/lib/BookDB/Schema/Result/Book.pm
+SHA1 e17c92e2a4cf1c5e7988f75f1161644daf0b263e t/lib/BookDB/Schema/Result/Book2PK.pm
 SHA1 0b13f30efa9317c7def84e10a007ed8a2e900d0e t/lib/BookDB/Schema/Result/BooksGenres.pm
-SHA1 3017b27ee8af6b022ddcb280aaf64cc6baeea3cb t/lib/BookDB/Schema/Result/Borrower.pm
+SHA1 8fdeb42fdfc15f2692fdc141ca4853ea3997b276 t/lib/BookDB/Schema/Result/Borrower.pm
 SHA1 025fa1a06df3677d577311cdf88190fca9c2ec9a t/lib/BookDB/Schema/Result/Country.pm
 SHA1 85dd3c2065ad98adb46ba52f1d02e1f5305d7dd1 t/lib/BookDB/Schema/Result/Employer.pm
 SHA1 42f9533e65597837b19389aef03b87096b3060b4 t/lib/BookDB/Schema/Result/Format.pm
@@ -85,50 +83,23 @@ SHA1 4efc958e6acf9822a75d27bf24d8cd1b08dc9e2a t/lib/BookDB/Schema/Result/License
 SHA1 7b72cbd79220d74553e66d662b17e1136e1c85b1 t/lib/BookDB/Schema/Result/Options.pm
 SHA1 caea8cb79f441d37d54e192d1bcc16763819a7ed t/lib/BookDB/Schema/Result/User.pm
 SHA1 c2b07809d8b836565eb70105704867668dfb7011 t/lib/BookDB/Schema/Result/UserEmployer.pm
-SHA1 481c05532681679b706917e4e90191344b181f7d t/lib/BookDB/View/TT.pm
-SHA1 554795112f0c741a23584fbd0078665ac87c767e t/lib/BookDB/root/book/form.tt
-SHA1 e143eaeaede4e19e820213e6d817d4cce12f102f t/lib/BookDB/root/book/list.tt
-SHA1 c1dc78a51e99083a5562387155f3c6604e63104d t/lib/BookDB/root/book/view.tt
-SHA1 34c8f267e59c4f3c891eaed81cceb4adfdada62b t/lib/BookDB/root/borrower/form.tt
-SHA1 471e2bb75d0fb3ec14886265e129ff9f8cf7dd00 t/lib/BookDB/root/borrower/list.tt
-SHA1 1330e21302c1f53978afd31ecc8d02610f79f6f5 t/lib/BookDB/root/borrower/view.tt
-SHA1 7bdb1e034041cbf3313dc597518e44660d3c2392 t/lib/BookDB/root/scaffold/footer.tt
-SHA1 cccca957b2e28e77beb288afacc465771ceae6af t/lib/BookDB/root/scaffold/header.tt
-SHA1 f09cee9125a639b2ebf9d50b947445ae1514753e t/lib/BookDB/root/scaffold/header_bg.jpg
-SHA1 83175ebb1e74976304bd867b848a1bb0b3d8dc8e t/lib/BookDB/root/scaffold/nav.tt
-SHA1 2abdd2ce4b3a24cd52f9cc66da0f05b8fc1d2446 t/lib/BookDB/root/scaffold/styles.css
-SHA1 c2399469ebe91bb0d93b7db3e3807068f9191e29 t/lib/BookDB/root/user/form.tt
-SHA1 1125626f4b5cb51609f8b7bdf3c917bdf1801654 t/lib/BookDB/root/user/list.tt
-SHA1 df4dd6bb06cbc01d8a96650eea83c667429db626 t/lib/BookDB/root/user/view.tt
-SHA1 28425bdc544de7e0d9ab2d74e52bcb4a0c178415 t/lib/BookDB/root/widget/checkbox.tt
-SHA1 8a4272af011a06a129fb29be255809956985539c t/lib/BookDB/root/widget/checkbox_group.tt
-SHA1 90d389dd6cd2ad7431f9172a225eea49975a3712 t/lib/BookDB/root/widget/form_end.tt
-SHA1 c062aaec08cb06f242c1bf91d7972afe4056ac96 t/lib/BookDB/root/widget/form_start.tt
-SHA1 a286c61d1a69273713b43505fc765298b54d50bf t/lib/BookDB/root/widget/multiple.tt
-SHA1 f852c1182e3c3e766b9cdd4359806c2ccc9e4a86 t/lib/BookDB/root/widget/radio.tt
-SHA1 2d4f9e4ada27db51506d45417aaa178d098ee92b t/lib/BookDB/root/widget/select.tt
-SHA1 ee477e100fbada00a0fe635c680f74ac35ff33ce t/lib/BookDB/root/widget/text.tt
-SHA1 e8b01c9c2d583f260108cab2283ba39303488f3f t/lib/BookDB/root/widget/textarea.tt
-SHA1 60f791ad0cd523be869b9f1994a89e8f3e5d7285 t/model_dbic.t
-SHA1 aaf01835ef5a500826c9a6505a6a6d9eb6ca1bf0 t/mult_pk.t
+SHA1 ffc28f0afa6b9c0b2022b64cafc36780eab8d131 t/model_dbic.t
+SHA1 6f7b36a0ecf0c47817f460a974c9cb62d004dbbd t/mult_pk.t
 SHA1 f7bd133652cf896d80d26912a2f96e9ca56a0e31 t/process.t
 SHA1 82bfaff07150d7a4e45d31bde7146c0622d44217 t/reflect.t
-SHA1 2a16e1ca8d089d093357b97db8bc9ddc390d0b80 t/related.t
+SHA1 d994766acb3f7185f996d7c2b2a6a8a1e02e802b t/related.t
 SHA1 a032c41ef6887fab1b900669c2d304fab46680e2 t/release-eol.t
-SHA1 455d1dd1867212a665ad5ea4126b572411de300c t/release-no-tabs.t
+SHA1 b3fe32c03277bf18bb496fa736bf9e1bdb3416cb t/release-no-tabs.t
 SHA1 a1731d1ac9e3a5218db578bc8557a0b0c068ac47 t/reload_options.t
 SHA1 f6d485d4fc868421b5f76a77cbe18e2b3068f95f t/resultset.t
-SHA1 f4a1ce3199d7c1ee7b41f31894148992ba63add2 t/script/bookdb_schema.pl
-SHA1 26dc02bbdeeec1b3756060cc5a5ebe50b9d380a1 t/script/bookdb_server.pl
-SHA1 1a61b93ee5714f47fcee75e8253ba37060fd7395 t/script/bookdb_test.pl
 SHA1 8e637403943525aa9fa41ae35e02c52225424220 t/unique-composite.t
-SHA1 3acf7f97a5d1ce5ab06bf03e9c4b626ac3a1403b t/unique.t
+SHA1 e5186c67e65b7c1658cdf2c362a05b3cea172d87 t/unique.t
 SHA1 86d255a7c9f065a13049108362c949b3e35a4c24 t/xt/02pod.t
 SHA1 6c8c9e4255f3a7e58a2508bb779ec013ac48706f t/xt/dump.t
 -----BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.10 (Darwin)
+Version: GnuPG/MacGPG2 v2.0.22 (Darwin)
 
-iF4EAREIAAYFAk+HkvcACgkQlX0ZOkgCuciB/gD+MGAdaNeyN/WrspxGsxUHJN0y
-HD3T4FtwmPzUpnFpsoIA/jjGGILqGQJLiyDjonn7IHUgQmXMj00Y5T7IMvMebmHi
-=HXXC
+iF4EAREIAAYFAlPr/R4ACgkQlX0ZOkgCucjUAAD/a4pFoi0mFvVa6+I/V9xNKcDy
+uOyDuircHkrdllvMR7oA/1kLim5RD11vE8l+hQPgvg44k6BOgVJLYqDuuGfBlbhd
+=CoHS
 -----END PGP SIGNATURE-----
@@ -4,9 +4,9 @@ name             = HTML-FormHandler-Model-DBIC
 author           = FormHandler Contributors - see HTML::FormHandler
 license          = Perl_5
 copyright_holder = Gerda Shank
-copyright_year   = 2012
+copyright_year   = 2013
 
-version = 0.19
+version = 0.29
 
 [@Git]
 tag_format = %v
@@ -35,14 +35,15 @@ repository.type   = git
 dir = script
 
 [Prereqs]
-HTML::FormHandler                       = 0.34001
+HTML::FormHandler                       = 0.40016
 Moose                                   = 2.0007
-DBIx::Class                             = 0
+DBIx::Class                             = 0.08250
 DBIx::Class::ResultSet::RecursiveUpdate = 0.25
 namespace::autoclean                    = 0.09
 
-[Prereq / TestRequires]
+[Prereqs / TestRequires]
 Test::More                = 0.94
+Test::Exception           = 0
 DateTime::Format::MySQL   = 0
 DateTime::Format::W3CDTF  = 0
 DateTime::Format::SQLite  = 0
@@ -116,7 +116,6 @@ my $form_template = <<'END';
     package [% config.class %]Form;
     use HTML::FormHandler::Moose;
     extends 'HTML::FormHandler::Model::DBIC';
-    with 'HTML::FormHandler::Render::Simple';
     use namespace::autoclean;
 [% FOR package = self.used_packages %]
     use [% package %];
@@ -360,15 +359,18 @@ use namespace::autoclean;
 1;
 
 __END__
+
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 HTML::FormHandler::Generator::DBIC - form generator for DBIC
 
 =head1 VERSION
 
-version 0.19
+version 0.29
 
 =head1 SYNOPSIS
 
@@ -400,10 +402,9 @@ FormHandler Contributors - see HTML::FormHandler
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 =cut
-
@@ -58,15 +58,18 @@ sub type_for_rel {
 1;
 
 __END__
+
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 HTML::FormHandler::Model::DBIC::TypeMap - type mape for DBICFields
 
 =head1 VERSION
 
-version 0.19
+version 0.29
 
 =head1 SYNOPSIS
 
@@ -78,10 +81,9 @@ FormHandler Contributors - see HTML::FormHandler
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 =cut
-
@@ -5,22 +5,25 @@ use Moose;
 extends 'HTML::FormHandler';
 with 'HTML::FormHandler::TraitFor::Model::DBIC';
 
-our $VERSION = '0.19';
+our $VERSION = '0.29';
 
 
 use namespace::autoclean;
 1;
 
 __END__
+
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 HTML::FormHandler::Model::DBIC - base class that holds DBIC model role
 
 =head1 VERSION
 
-version 0.19
+version 0.29
 
 =head1 SUMMARY
 
@@ -33,10 +36,9 @@ FormHandler Contributors - see HTML::FormHandler
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 =cut
-
@@ -94,15 +94,18 @@ sub field_for_rel {
 1;
 
 __END__
+
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 HTML::FormHandler::TraitFor::DBICFields - role to get fields from DBIx::Class result source
 
 =head1 VERSION
 
-version 0.19
+version 0.29
 
 =head1 SYNOPSIS
 
@@ -150,10 +153,9 @@ FormHandler Contributors - see HTML::FormHandler
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 =cut
-
@@ -1,4 +1,5 @@
 package HTML::FormHandler::TraitFor::Model::DBIC;
+
 # ABSTRACT: model role that interfaces with DBIx::Class
 
 use Moose::Role;
@@ -8,416 +9,426 @@ use DBIx::Class::ResultClass::HashRefInflator;
 use DBIx::Class::ResultSet::RecursiveUpdate;
 use Scalar::Util ('blessed');
 
-our $VERSION = '0.14';
+our $VERSION = '0.26';
 
 
-has 'schema' => (
-   is      => 'rw',
-);
+has 'schema' => ( is => 'rw', );
 has 'source_name' => (
-   isa     => 'Str',
-   is      => 'rw',
-   lazy    => 1,
-   builder => 'build_source_name'
+    isa     => 'Str',
+    is      => 'rw',
+    lazy    => 1,
+    builder => 'build_source_name'
 );
 
 has unique_constraints => (
-   is         => 'ro',
-   isa        => 'ArrayRef',
-   lazy_build => 1,
+    is         => 'ro',
+    isa        => 'ArrayRef',
+    lazy_build => 1,
 );
+
 sub _build_unique_constraints {
-   my $self = shift;
-   return [grep { $_ ne 'primary' } $self->resultset->result_source->unique_constraint_names];
+    my $self = shift;
+    return [ grep { $_ ne 'primary' }
+            $self->resultset->result_source->unique_constraint_names ];
 }
 
 has unique_messages => (
-   is      => 'ro',
-   isa     => 'HashRef',
-   default => sub { +{} },
+    is      => 'ro',
+    isa     => 'HashRef',
+    default => sub { +{} },
 );
 
 has 'ru_flags' => (
-   is => 'rw',
-   isa => 'HashRef',
-   traits => ['Hash'],
-   builder => '_build_ru_flags',
-   handles => {
-       set_ru_flag => 'set',
-   }
+    is      => 'rw',
+    isa     => 'HashRef',
+    traits  => ['Hash'],
+    builder => '_build_ru_flags',
+    handles => { set_ru_flag => 'set', }
 );
+
 sub _build_ru_flags {
-    { unknown_params_ok => 1 }
+    { unknown_params_ok => 1 };
 }
 
-sub validate_model
-{
-   my ($self) = @_;
-   return unless $self->validate_unique;
-   return 1;
+sub validate_model {
+    my ($self) = @_;
+    return unless $self->validate_unique;
+    return 1;
 }
 
-sub clear_model
-{
-   my $self = shift;
-   $self->item(undef);
-   $self->item_id(undef);
+sub clear_model {
+    my $self = shift;
+    $self->item(undef);
+    $self->item_id(undef);
 }
 
-sub update_model
-{
-    my $self = shift;
+sub update_model {
+    my $self   = shift;
     my $item   = $self->item;
     my $source = $self->source;
 
     warn "HFH: update_model for ", $self->name, "\n" if $self->verbose;
+
     #warn "fif: " . Dumper ( $self->fif ); use Data::Dumper;
     my %update_params = (
         resultset => $self->resultset,
-        updates => $self->values,
-        %{$self->ru_flags},
+        updates   => $self->values,
+        %{ $self->ru_flags },
     );
-    $update_params{ object } = $self->item if $self->item;
+    $update_params{object} = $self->item if $self->item;
     my $new_item;
+
     # perform update in a transaction, since RecursiveUpdate may do multiple
     # updates if there are compound or multiple fields
-    $self->schema->txn_do( sub {
-        $new_item = DBIx::Class::ResultSet::RecursiveUpdate::Functions::recursive_update( %update_params );
-        $new_item->discard_changes;
-    });
+    $self->schema->txn_do(
+        sub {
+            $new_item = DBIx::Class::ResultSet::RecursiveUpdate::Functions::recursive_update(
+                %update_params);
+            $new_item->discard_changes;
+        }
+    );
     $self->item($new_item) if $new_item;
     return $self->item;
 }
 
 # undocumented because this is going to be replaced
 # by a better method
-sub guess_field_type
-{
-   my ( $self, $column ) = @_;
-   my $source = $self->source;
-   my @return;
-
-   #  TODO: Should be able to use $source->column_info
-
-   # Is it a direct has_a relationship?
-   if (
-      $source->has_relationship($column)
-      && (  $source->relationship_info($column)->{attrs}->{accessor} eq 'single'
-         || $source->relationship_info($column)->{attrs}->{accessor} eq 'filter' )
-      )
-   {
-      my $f_class = $source->related_class($column);
-      @return =
-         $f_class->isa('DateTime')
-         ? ('DateTime')
-         : ('Select');
-   }
-   # Else is it has_many?
-   elsif ( $source->has_relationship($column)
-      && $source->relationship_info($column)->{attrs}->{accessor} eq 'multi' )
-   {
-      @return = ('Multiple');
-   }
-   elsif ( $column =~ /_time$/ )    # ends in time, must be time value
-   {
-      @return = ('DateTime');
-   }
-   else                             # default: Text
-   {
-      @return = ('Text');
-   }
-
-   return wantarray ? @return : $return[0];
+sub guess_field_type {
+    my ( $self, $column ) = @_;
+    my $source = $self->source;
+    my @return;
+
+    #  TODO: Should be able to use $source->column_info
+
+    # Is it a direct has_a relationship?
+    if (
+        $source->has_relationship($column) &&
+        ( $source->relationship_info($column)->{attrs}->{accessor} eq 'single' ||
+            $source->relationship_info($column)->{attrs}->{accessor} eq 'filter' )
+        )
+    {
+        my $f_class = $source->related_class($column);
+        @return =
+            $f_class->isa('DateTime') ? ('DateTime') :
+                                        ('Select');
+    }
+
+    # Else is it has_many?
+    elsif ( $source->has_relationship($column) &&
+        $source->relationship_info($column)->{attrs}->{accessor} eq 'multi' )
+    {
+        @return = ('Multiple');
+    }
+    elsif ( $column =~ /_time$/ )    # ends in time, must be time value
+    {
+        @return = ('DateTime');
+    }
+    else                             # default: Text
+    {
+        @return = ('Text');
+    }
+
+    return wantarray ? @return : $return[0];
 }
 
+sub lookup_options {
+    my ( $self, $field, $accessor_path ) = @_;
+
+    return unless $self->schema;
+    my $self_source = $self->get_source($accessor_path);
+
+    my $accessor = $field->accessor;
+
+    # if this field doesn't refer to a foreign key, return
+    my $f_class;
+    my $source;
+
+    # belongs_to single select
+    if ( $self_source->has_relationship($accessor) ) {
+        $f_class = $self_source->related_class($accessor);
+        $source  = $self->schema->source($f_class);
+    }
+    else {
+
+        # check for many_to_many multiple select
+        my $resultset = $self_source->resultset;
+        my $new_result = $resultset->new_result( {} );
+        if ( $new_result && $new_result->can("add_to_$accessor") ) {
+            $source = $new_result->$accessor->result_source;
+        }
+    }
+    return unless $source;
+
+    my $label_column = $field->label_column;
+    return
+        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 $sort_col = $field->sort_column;
+    my ($primary_key) = $source->primary_columns;
+
+    # if no sort_column and label_column is a source method, not a real column, must
+    # use some other column for sort. There's probably some other column that should
+    # be specified, but this will prevent breakage
+    if ( !defined $sort_col ) {
+        $sort_col = $source->has_column($label_column) ? $label_column : $primary_key;
+    }
+
+    # If there's an active column, only select active OR items already selected
+    my $criteria = {};
+    if ($active_col) {
+        my @or = ( $active_col => 1 );
 
-sub lookup_options
-{
-   my ( $self, $field, $accessor_path ) = @_;
-
-   return unless $self->schema;
-   my $self_source = $self->get_source( $accessor_path );
-
-   my $accessor = $field->accessor;
-
-   # if this field doesn't refer to a foreign key, return
-   my $f_class;
-   my $source;
-   # belongs_to single select
-   if ($self_source->has_relationship($accessor) ) {
-       $f_class = $self_source->related_class($accessor);
-       $source = $self->schema->source($f_class);
-   }
-   else {
-       # check for many_to_many multiple select
-       my $resultset = $self_source->resultset;
-       my $new_result = $resultset->new_result({});
-       if( $new_result && $new_result->can("add_to_$accessor") ) {
-          $source = $new_result->$accessor->result_source;
-       }
-   }
-   return unless $source;
-
-   my $label_column = $field->label_column;
-   return unless ($source->has_column($label_column) || $source->can($label_column) );
-
-   my $active_col = $self->active_column || $field->active_column;
-   $active_col = '' unless $source->has_column($active_col);
-   my $sort_col = $field->sort_column;
-   my ($primary_key) = $source->primary_columns;
-
-   # if no sort_column and label_column is a source method, not a real column, must
-   # use some other column for sort. There's probably some other column that should
-   # be specified, but this will prevent breakage
-   if ( !(defined $sort_col && $source->has_column($sort_col)) ) {
-       $sort_col = $source->has_column($label_column) ? $label_column : $primary_key;
-   }
-
-
-   # If there's an active column, only select active OR items already selected
-   my $criteria = {};
-   if ($active_col)
-   {
-      my @or = ( $active_col => 1 );
-
-      # But also include any existing non-active
-      push @or, ( "$primary_key" => $field->init_value )
-         if $self->item && defined $field->init_value;
-      $criteria->{'-or'} = \@or;
-   }
-
-   # get an array of row objects
-   my @rows =
-      $self->schema->resultset( $source->source_name )
-      ->search( $criteria, { order_by => $sort_col } )->all;
-   my @options;
-   foreach my $row (@rows)
-   {
-      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";
-   }
-   return \@options;
+        # But also include any existing non-active
+        push @or, ( "$primary_key" => $field->init_value )
+            if $self->item && defined $field->init_value;
+        $criteria->{'-or'} = \@or;
+    }
+
+    # get an array of row objects
+    my @rows =
+        $self->schema->resultset( $source->source_name )
+        ->search( $criteria, { order_by => $sort_col } )->all;
+    my @options;
+    foreach my $row (@rows) {
+        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";
+    }
+    return \@options;
 }
 
-sub init_value
-{
-   my ( $self, $field, $value ) = @_;
-   if( ref $value eq 'ARRAY' ){
-       $value = [ map { $self->_fix_value( $field, $_ ) } @$value ];
-   }
-   else{
-       $value = $self->_fix_value( $field, $value );
-   }
-   $field->init_value($value);
-   $field->value($value);
+sub init_value {
+    my ( $self, $field, $value ) = @_;
+    if ( ref $value eq 'ARRAY' ) {
+        $value = [ map { $self->_fix_value( $field, $_ ) } @$value ];
+    }
+    else {
+        $value = $self->_fix_value( $field, $value );
+    }
+    $field->init_value($value);
+    $field->value($value);
 }
 
-sub _fix_value
-{
-   my ( $self, $field, $value ) = @_;
-   if( blessed $value && $value->isa('DBIx::Class') ){
-       return $value->id;
-   }
-   return $value;
+sub _fix_value {
+    my ( $self, $field, $value ) = @_;
+    if ( blessed $value && $value->isa('DBIx::Class') ) {
+        return $value->id;
+    }
+    return $value;
 }
 
 sub _get_related_source {
     my ( $self, $source, $name ) = @_;
 
-    if( $source->has_relationship( $name ) ){
-        return $source->related_source( $name );
+    if ( $source->has_relationship($name) ) {
+        return $source->related_source($name);
     }
+
     # many to many case
-    my $row = $source->resultset->new({});
-    if ( $row->can( $name ) and $row->can( 'add_to_' . $name ) and $row->can( 'set_' . $name ) ){
+    my $row = $source->resultset->new( {} );
+    if ( $row->can($name) and
+        $row->can( 'add_to_' . $name ) and
+        $row->can( 'set_' . $name ) )
+    {
         return $row->$name->result_source;
     }
     return;
 }
 
-
 # this needs to be rewritten to be called at the field level
 # right now it will only work on fields immediately contained
 # by the form
-sub validate_unique
-{
-   my ($self) = @_;
-
-   my $rs          = $self->resultset;
-   my $found_error = 0;
-   my $fields      = $self->fields;
-
-   my @id_clause = ();
-   @id_clause = _id_clause( $rs, $self->item_id ) if defined $self->item;
-
-   my $value = $self->value;
-   for my $field ( @$fields )
-   {
-      next unless $field->unique;
-      next if $field->has_errors;
-      my $value = $field->value;
-      next unless defined $value;
-      my $accessor   = $field->accessor;
-
-      my $count = $rs->search( { $accessor => $value, @id_clause } )->count;
-      next if $count < 1;
-      my $field_error = $field->unique_message || 'Duplicate value for [_1]';
-      $field->add_error( $field_error, $field->loc_label );
-      $found_error++;
-   }
-
-   # validate unique constraints in the model
-   for my $constraint (@{ $self->unique_constraints })
-   {
-      my @columns = $rs->result_source->unique_constraint_columns($constraint);
-
-      # check for matching field in the form
-      my $field;
-      for my $col (@columns)
-      {
-         ($field) = grep { $_->accessor eq $col } @$fields;
-         last if $field;
-      }
-      next unless defined $field;
-      next if ( $field->has_unique ); # already handled or don't do
-
-      my @values = map {
-         exists( $value->{$_} ) ? $value->{$_} : undef
-            ||
-         ( $self->item ? $self->item->get_column($_) : undef )
-      } @columns;
-
-      next if @columns != @values; # don't check unique constraints for which we don't have all the values
-      next if grep { !defined $_ } @values; # don't check unique constraints with NULL values
-
-      my %where;
-      @where{@columns} = @values;
-      my $count = $rs->search( \%where )->search({@id_clause})->count;
-      next if $count < 1;
+sub validate_unique {
+    my ($self) = @_;
+
+    my $rs          = $self->resultset;
+    my $found_error = 0;
+    my $fields      = $self->fields;
+
+    my @id_clause = ();
+    @id_clause = _id_clause( $rs, $self->item_id ) if defined $self->item;
+
+    my $value = $self->value;
+    for my $field (@$fields) {
+        next unless $field->unique;
+        next if ( $field->is_inactive || !$field->has_result );
+        next if $field->has_errors;
+        my $value = $field->value;
+        next unless defined $value;
+        my $accessor = $field->accessor;
+
+        my $count = $rs->search( { $accessor => $value, @id_clause } )->count;
+        next if $count < 1;
+        my $field_error = $field->get_message('unique') || $field->unique_message || 'Duplicate value for [_1]';
+        $field->add_error( $field_error, $field->loc_label );
+        $found_error++;
+    }
 
-      my $field_error = $self->unique_message_for_constraint($constraint);
-      $field->add_error( $field_error, $constraint );
-      $found_error++;
-   }
+    # validate unique constraints in the model
+    for my $constraint ( @{ $self->unique_constraints } ) {
+        my @columns = $rs->result_source->unique_constraint_columns($constraint);
+
+        # check for matching field in the form
+        my $field;
+        for my $col (@columns) {
+            ($field) = grep { $_->accessor eq $col } @$fields;
+            last if $field;
+        }
+        next unless defined $field;
+        next if ( $field->has_unique );    # already handled or don't do
+
+        my @values = map {
+            exists( $value->{$_} ) ? $value->{$_} : undef ||
+                ( $self->item ? $self->item->get_column($_) : undef )
+        } @columns;
+
+        next
+            if @columns !=
+                @values; # don't check unique constraints for which we don't have all the values
+        next
+            if grep { !defined $_ } @values;   # don't check unique constraints with NULL values
+
+        my %where;
+        @where{@columns} = @values;
+        my $count = $rs->search( \%where )->search( {@id_clause} )->count;
+        next if $count < 1;
+
+        my $field_error = $self->unique_message_for_constraint($constraint);
+        $field->add_error( $field_error, $constraint );
+        $found_error++;
+    }
 
-   return $found_error;
+    return $found_error;
 }
 
 sub unique_message_for_constraint {
-   my $self       = shift;
-   my $constraint = shift;
+    my $self       = shift;
+    my $constraint = shift;
 
-   return $self->unique_messages->{$constraint} ||= "Duplicate value for [_1] unique constraint";
+    return $self->unique_messages->{$constraint} ||=
+        "Duplicate value for [_1] unique constraint";
 }
 
 sub _id_clause {
-    my( $resultset, $id ) = @_;
+    my ( $resultset, $id ) = @_;
+
     my @pks = $resultset->result_source->primary_columns;
-    my @ids;
-    if( ref $id eq 'ARRAY' ){
-        @ids = @$id;
+    my %clause;
+    # multiple primary key
+    if ( scalar @pks > 1 ) {
+        die "multiple primary key invalid" if ref $id ne 'ARRAY';
+        my $cond = $id->[0];
+        my @phrase;
+        foreach my $col ( keys %$cond ) {
+            $clause{$col} = { '!=' => $cond->{$col} };
+        }
     }
-    else{
-        @ids = ( $id );
+    else {
+        %clause = ( $pks[0] => { '!=' => $id } );
     }
-    my %result;
-    for my $i ( $#ids ){
-        $result{$pks[$i]} = { '!=' => $ids[$i] };
-    }
-    return %result;
+    return %clause;
 }
 
-sub build_item
-{
-   my $self = shift;
+sub build_item {
+    my $self = shift;
 
-   my $item_id = $self->item_id or return;
-   my $item = $self->resultset->find( ref $item_id eq 'ARRAY' ?
-                @{$item_id} : $item_id);
-   $self->item_id(undef) unless $item;
-   return $item;
+    my $item_id = $self->item_id or return;
+    my $item = $self->resultset->find( ref $item_id eq 'ARRAY' ? @{$item_id} : $item_id );
+    $self->item_id(undef) unless $item;
+    return $item;
 }
 
-sub set_item
-{
-   my ( $self, $item ) = @_;
-   return unless $item;
-   # when the item (DBIC row) is set, set the item_id, item_class
-   # and schema from the item
-   if( $item->id )
-   { $self->item_id($item->id); }
-   else
-   { $self->clear_item_id; }
-   $self->item_class( $item->result_source->source_name );
-   $self->schema( $item->result_source->schema );
-}
+sub set_item {
+    my ( $self, $item ) = @_;
+    return unless $item;
 
-sub set_item_id
-{
-   my ( $self, $item_id ) = @_;
-   # if a new item_id has been set
-   # clear an existing item
-   if( defined $self->item )
-   {
-      $self->clear_item
-         if( !defined $item_id ||
-             (ref $item_id eq 'ARRAY' &&
-              join('', @{$item_id}) ne join('', $self->item->id)) ||
-             (ref \$item_id eq 'SCALAR' &&
-              $item_id ne $self->item->id));
-   }
+    # when the item (DBIC row) is set, set the item_id, item_class
+    # and schema from the item
+    my @primary_columns = $item->result_source->primary_columns;
+    my $item_id;
+    if ( @primary_columns == 1 ) {
+        $item_id = $item->get_column( $primary_columns[0] );
+    }
+    elsif ( @primary_columns > 1 ) {
+        my @pks = map {  $_ => $item->get_column($_) } @primary_columns;
+        $item_id = [ { @pks }, { key => 'primary' } ];
+    }
+    if ($item_id) {
+        $self->item_id($item_id);
+    }
+    else {
+        $self->clear_item_id;
+    }
+    $self->item_class( $item->result_source->source_name );
+    $self->schema( $item->result_source->schema );
 }
 
-
-sub build_source_name
-{
-   my $self = shift;
-   return $self->item_class;
+sub set_item_id {
+    my ( $self, $item_id ) = @_;
+
+    # if a new item_id has been set
+    # clear an existing item
+    if ( defined $self->item ) {
+        $self->clear_item
+            if (
+            !defined $item_id ||
+            ( ref $item_id eq 'ARRAY' &&
+                join( '', @{$item_id} ) ne join( '', $self->item->id ) ) ||
+            ( ref \$item_id eq 'SCALAR' &&
+                $item_id ne $self->item->id )
+            );
+    }
 }
 
+sub build_source_name {
+    my $self = shift;
+    return $self->item_class;
+}
 
-sub source
-{
-   my ( $self, $f_class ) = @_;
-   return $self->schema->source( $self->source_name || $self->item_class );
+sub source {
+    my ( $self, $f_class ) = @_;
+    return $self->schema->source( $self->source_name || $self->item_class );
 }
 
-sub resultset
-{
-   my ( $self, $f_class ) = @_;
-   die "You must supply a schema for your FormHandler form" unless $self->schema;
-   return $self->schema->resultset( $self->source_name || $self->item_class );
+sub resultset {
+    my ( $self, $f_class ) = @_;
+    die "You must supply a schema for your FormHandler form"
+        unless $self->schema;
+    return $self->schema->resultset( $self->source_name || $self->item_class );
 }
 
-sub get_source
-{
-   my ( $self, $accessor_path ) = @_;
-   return unless $self->schema;
-   my $source = $self->source;
-   return $source unless $accessor_path;
-   my @accessors = split /\./, $accessor_path;
-   for my $accessor ( @accessors )
-   {
-       $source = $self->_get_related_source( $source, $accessor );
-       die "unable to get source for $accessor" unless $source;
-   }
-   return $source;
+sub get_source {
+    my ( $self, $accessor_path ) = @_;
+    return unless $self->schema;
+    my $source = $self->source;
+    return $source unless $accessor_path;
+    my @accessors = split /\./, $accessor_path;
+    for my $accessor (@accessors) {
+        $source = $self->_get_related_source( $source, $accessor );
+        die "unable to get source for $accessor" unless $source;
+    }
+    return $source;
 }
 
 use namespace::autoclean;
 1;
 
 __END__
+
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 HTML::FormHandler::TraitFor::Model::DBIC - model role that interfaces with DBIx::Class
 
 =head1 VERSION
 
-version 0.19
+version 0.29
 
 =head1 SYNOPSIS
 
@@ -436,11 +447,11 @@ or apply as a role to FormHandler class:
 
 =head1 DESCRIPTION
 
-This is a separate L<DBIx::Class> model role for L<HTML::FormHandler>. It will save
-form fields automatically to the database. The distribution
-contains an example application (execute with t/script/bookdb_server.pl) and a form
-generator (L<HTML::FormHandler::Generator::DBIC>).
+This is a separate L<DBIx::Class> model role for L<HTML::FormHandler>.
 It will handle normal DBIC column accessors and a number of DBIC relationships.
+It will save form fields automatically to the database. The distribution contains a form
+generator (L<HTML::FormHandler::Generator::DBIC>). An example application can
+be found on github at http://github.com/gshank/formhandler-example.
 
 L<HTML::FormHandler::TraitFor::DBICFields> can be used to auto-generate forms
 from a DBIC result.
@@ -576,10 +587,8 @@ The currently selected values in a Multiple list are grouped at the top
 
 =head2 init_value
 
-This method sets a field's value (for $field->value).
-
-This method is not called if a method "init_value_$field_name" is found
-in the form class - that method is called instead.
+This method sets a field's initial value. it is set when values are
+initially loaded from an item, init_object or field defaults.
 
 =head2 validate_unique
 
@@ -635,10 +644,9 @@ FormHandler Contributors - see HTML::FormHandler
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 =cut
-
@@ -11,17 +11,19 @@ my $generator = HTML::FormHandler::Generator::DBIC::Cmd->new_with_options();
 
 print $generator->generate_form;
 
-
 __END__
+
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 form_generator - form generator
 
 =head1 VERSION
 
-version 0.19
+version 0.29
 
 =head1 AUTHOR
 
@@ -29,10 +31,9 @@ FormHandler Contributors - see HTML::FormHandler
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is copyright (c) 2012 by Gerda Shank.
+This software is copyright (c) 2013 by Gerda Shank.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 =cut
-
@@ -0,0 +1,34 @@
+use strict;
+use warnings;
+use Test::More;
+use lib 't/lib';
+use BookDB::Schema;
+
+{
+    package MyApp::Form::Test;
+    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 => 'is_active',
+    );
+}
+
+my $schema = BookDB::Schema->connect('dbi:SQLite:t/db/book.db');
+my $form = MyApp::Form::Test->new( schema => $schema );
+
+ok( $form );
+
+is( $form->field('genres')->num_options, 3, 'right number of options' );
+
+done_testing;
+
@@ -17,6 +17,13 @@ my $form = BookDB::Form::Book->new;
 
 ok( !$form->process( item => $item ), 'Empty data' );
 
+# check authors options
+my $author_options = $form->field('authors')->options;
+is( $author_options->[0]->{label}, 'J.K. Rowling', 'right author name');
+
+my $borrower_options = $form->field('borrower')->options;
+is( $borrower_options->[1]->{label}, 'John Doe <john@gmail.com>', 'right borrower name');
+
 # This is munging up the equivalent of param data from a form
 my $good = {
     'title' => 'How to Test Perl Form Processors',
@@ -27,6 +34,7 @@ my $good = {
     'publisher' => 'EreWhon Publishing',
     'user_updated' => 1,
     'comment' => 'this is a comment',
+    'borrower' => undef,
 };
 
 ok( $form->process( item => $item, params => $good ), 'Good data' );
@@ -38,7 +46,7 @@ ok ($book, 'get book object from form');
 
 is( $book->extra, 'this is a comment', 'comment exists' );
 is_deeply( $form->values, $good, 'values correct' );
-$good->{$_} = '' for qw/ year pages/;
+$good->{$_} = '' for qw/ year pages borrower/;
 is_deeply( $form->fif, $good, 'fif correct' );
 
 my $num_genres = $book->genres->count;
@@ -62,7 +70,8 @@ is( $form->field('publisher')->value, 'EreWhon Publishing', 'right publisher');
 my $value_hash = { %{$good},
                    authors => [],
                    year => undef,
-                   pages => undef
+                   pages => undef,
+                   borrower => undef,
                  };
 delete $value_hash->{submit};
 is_deeply( $form->values, $value_hash, 'get right values from form');
@@ -111,7 +120,7 @@ $form->process( $good );
 is( $book->genres->count, 0, 'multiple select list has no selected options');
 
 $form = BookDB::Form::Book->new(schema => $schema, active_column => 'is_active');
-is( scalar @{$form->field( 'genres' )->options}, 0, 'active_column test' );
+is( $form->field( 'genres' )->num_options, 3, 'active_column test' );
 
 {
     package Test::Book;
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+use Test::More;
+use Test::Exception;
+use lib 't/lib';
+
+
+use_ok( 'BookDB::Form::Book2PK');
+
+use_ok( 'BookDB::Schema');
+
+my $schema = BookDB::Schema->connect('dbi:SQLite:t/db/book.db');
+
+my $book = $schema->resultset('Book2PK')->find( { libraryid => 1, id => 1 }, { key => 'primary' });
+my $form = BookDB::Form::Book2PK->new;
+ok( $form );
+
+$form->process( item => $book, params => {} );
+my $params = $form->fif;
+my $orig_pages = $params->{pages};
+$params->{pages} = 500;
+lives_ok( sub { $form->process( item => $book, params => $params ) }, 'multiple pk works' );
+$book->discard_changes;
+is( $book->pages, 500, 'pages changed' );
+
+$params->{pages} = $orig_pages;
+$form->process( item => $book, params => $params );
+
+
+done_testing;
@@ -11,15 +11,13 @@ my $field = HTML::FormHandler::Field::DateTime->new( name => 'test_field' );
 ok( defined $field, 'new() called' );
 
 {
+    package UserForm;
 
-package UserForm;
+    use HTML::FormHandler::Moose;
+    extends 'HTML::FormHandler::Model::DBIC';
 
-use HTML::FormHandler::Moose;
-extends 'HTML::FormHandler::Model::DBIC';
-with 'HTML::FormHandler::Render::Simple';
-
-has_field 'birthdate'      => ( type => 'DateTime' );
-has_field 'birthdate.year' => ( type => 'Year' );
+    has_field 'birthdate'      => ( type => 'DateTime' );
+    has_field 'birthdate.year' => ( type => 'Year' );
 }
 
 my $schema = BookDB::Schema->connect('dbi:SQLite:t/db/book.db');
diff --git a/var/tmp/source/GSHANK/HTML-FormHandler-Model-DBIC-0.19/HTML-FormHandler-Model-DBIC-0.19/t/db/book.db b/var/tmp/source/GSHANK/HTML-FormHandler-Model-DBIC-0.29/HTML-FormHandler-Model-DBIC-0.29/t/db/book.db
index 9e73fa7e..2a4a1d40 100644
Binary files a/var/tmp/source/GSHANK/HTML-FormHandler-Model-DBIC-0.19/HTML-FormHandler-Model-DBIC-0.19/t/db/book.db and b/var/tmp/source/GSHANK/HTML-FormHandler-Model-DBIC-0.29/HTML-FormHandler-Model-DBIC-0.29/t/db/book.db differ
@@ -178,12 +178,12 @@ CREATE TABLE genre (
     name varchar(100),
     is_active INTEGER
 );
-INSERT INTO "genre" VALUES(1, 'Sci-Fi', NULL);
-INSERT INTO "genre" VALUES(2, 'Computers', NULL);
+INSERT INTO "genre" VALUES(1, 'Sci-Fi', 1);
+INSERT INTO "genre" VALUES(2, 'Computers', 1);
 INSERT INTO "genre" VALUES(3, 'Mystery', NULL);
 INSERT INTO "genre" VALUES(4, 'Historical', NULL);
 INSERT INTO "genre" VALUES(5, 'Fantasy', NULL);
-INSERT INTO "genre" VALUES(6, 'Technical', NULL);
+INSERT INTO "genre" VALUES(6, 'Technical', 1);
 CREATE TABLE author_old (
    first_name VARCHAR(100),
    last_name VARCHAR(100),
@@ -278,4 +278,26 @@ CREATE TABLE roles (
 
 CREATE UNIQUE INDEX unique_role ON roles (display_value);
 
+CREATE TABLE book2pk (
+    libraryid INTEGER NOT NULL DEFAULT 1,
+    id INTEGER NOT NULL,
+    isbn varchar(100),
+    title varchar(100),
+    publisher varchar(100),
+    pages int,
+    year int,
+    PRIMARY KEY (libraryid, id)
+);
+
+CREATE UNIQUE INDEX isbn ON book2pk (libraryid, isbn);
+
+INSERT INTO "book2pk" VALUES(1,1, '0-7475-5100-6', 'Harry Potter and the Order of the Phoenix', 'Boomsbury', 766, 2001);
+INSERT INTO "book2pk" VALUES(1,2, '9 788256006199', 'Idioten', 'Interbook', 303, 1901);
+INSERT INTO "book2pk" VALUES(1,3, '434012386', 'The Confusion', 'Heinemann', 345, 2002);
+INSERT INTO "book2pk" VALUES(1,4, '782128254', 'The Complete Java 2 Certification Study Guide: Programmer''s and Developers Exams (With CD-ROM)', 'Sybex Inc', NULL, 1999);
+INSERT INTO "book2pk" VALUES(1,5, '123-1234-0-123', 'Winnie The Pooh', 'Houghton Mifflin', 345, 1935);
+INSERT INTO "book2pk" VALUES(1,6, '0-596-10092-2', 'Perl Testing: A Developer''s Notebook', 'O''Reilly', 182, 2005);
+INSERT INTO "book2pk" VALUES(1,7, '0-7475-8134-6', 'Harry Potter and the Last Gasp', 'Boomsbury', 801, 2005);
+
+
 COMMIT;
@@ -25,6 +25,7 @@ my $validated = $form->process( $bad );
 ok( $validated, 'now form validates' );
 
 $form->update_model;
+$book = $form->item;
 is( $book->year, 1999, 'book has been updated with correct data' );
 
 done_testing;
@@ -40,6 +40,7 @@ is_deeply( $fif, {
       format => '',
       year => '',
       user_updated => 0,
+      borrower => '',
    }, 'get form fif' );
 
 $fif->{pages} = '501';
@@ -81,7 +82,7 @@ is( $form->field('pages')->fif, 699, 'get field fif after validation' );
 
 is( $form->field('isbn')->fif, '02340234', 'get field author after validation' );
 
-$params->{$_} = '' for qw/ comment format year /;
+$params->{$_} = '' for qw/ comment format year borrower /;
 $params->{user_updated} = 0;
 is_deeply( $form->fif, $params, 'get form fif after validation' );
 
@@ -1,108 +0,0 @@
-package BookDB::Controller::Author;
-
-use Moose;
-BEGIN {
-   extends 'Catalyst::Controller';
-}
-
-use BookDB::Form::User;
-
-has 'author_form' => ( isa => 'BookDB::Form::Author', is => 'rw',
-   lazy => 1, default => sub { BookDB::Form::Author->new } );
-
-=head1 NAME
-
-BookDB::Controller::Author
-
-=head1 SYNOPSIS
-
-An author form
-
-=head1 DESCRIPTION
-
-User Controller
-
-=cut
-
-
-sub author_base : Chained PathPart('author') CaptureArgs(0)
-{
-   my ( $self, $c ) = @_;
-}
-
-sub default : Chained('author_base') PathPart('') Args
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub list : Chained('author_base') PathPart('list') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub do_list
-{
-   my ( $self, $c ) = @_;
-
-   my $authors = [ $c->model('DB::Author')->all ];
-   $c->stash( authors => $authors, template => 'user/list.tt' );
-}
-
-sub create : Chained('author_base') PathPart('create') Args(0)
-{
-   my ( $self, $c ) = @_;
-   # Create the empty author row for the form
-   $c->stash( author => $c->model('DB::Author')->new_result({}) );
-   return $self->form($c);
-}
-
-sub item : Chained('author_base') PathPart('') CaptureArgs(1)
-{
-   my ( $self, $c, $author_id ) = @_;
-   $c->stash( author => $c->model('DB::Author')->find($author_id) );
-}
-
-sub edit : Chained('item') PathPart('edit') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->form($c);
-}
-
-sub form
-{
-   my ( $self, $c ) = @_;
-
-   $c->stash( form => $self->author_form, template => 'author/form.tt',
-      action => $c->chained_uri_for->as_string );
-   return unless $self->form->validate( $c->stash->{author},
-      params => $c->req->parameters );
-   $c->res->redirect( $c->uri_for('list') );
-}
-
-sub delete : Chained('item') PathPart('delete') Args(0)
-{
-   my ( $self, $c ) = @_;
-
-   $c->stash->{author}->delete;
-   $c->res->redirect( $c->uri_for('list') );
-}
-
-sub view : Chained('item') PathPart('') Args(0) { }
-
-
-=back
-
-=head1 AUTHOR
-
-Gerda Shank
-
-=head1 LICENSE
-
-This library is free software . You can redistribute it and/or modify
-it under the same terms as perl itself.
-
-=cut
-
-1;
@@ -1,135 +0,0 @@
-package BookDB::Controller::Book;
-
-use Moose;
-BEGIN {
-   extends 'Catalyst::Controller';
-}
-
-use BookDB::Form::Book;
-use BookDB::Form::BookView;
-
-has 'edit_form' => ( isa => 'BookDB::Form::Book', is => 'rw',
-   lazy => 1, default => sub { BookDB::Form::Book->new } );
-has 'view_form' => ( isa => 'BookDB::Form::BookView', is => 'rw',
-   lazy => 1, default => sub { BookDB::Form::BookView->new } );
-
-=head1 NAME
-
-BookDB::Controller::Book
-
-=head1 SYNOPSIS
-
-See L<BookDB>
-
-=head1 DESCRIPTION
-
-Book Controller
-
-=cut
-
-
-sub book_base : Chained PathPart('book') CaptureArgs(0)
-{
-   my ( $self, $c ) = @_;
-}
-
-sub default : Chained('book_base') PathPart('') Args
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub list : Chained('book_base') PathPart('list') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub do_list
-{
-   my ( $self, $c ) = @_;
-
-   my $books = [ $c->model('DB::Book')->all ];
-   my @columns = ( 'title', 'author_list', 'publisher', 'year' );
-   $c->stash( books => $books, columns => \@columns,
-              template => 'book/list.tt' );
-}
-
-sub create : Chained('book_base') PathPart('create') Args(0)
-{
-   my ( $self, $c ) = @_;
-   # Create the empty book row for the form
-   $c->stash( book => $c->model('DB::Book')->new_result({}) );
-   return $self->form($c);
-}
-
-sub item : Chained('book_base') PathPart('') CaptureArgs(1)
-{
-   my ( $self, $c, $book_id ) = @_;
-   $c->stash( book => $c->model('DB::Book')->find($book_id) );
-}
-
-sub edit : Chained('item') PathPart('edit') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->form($c);
-}
-
-sub form
-{
-   my ( $self, $c ) = @_;
-
-   my $result = $self->edit_form->run( item => $c->stash->{book},
-      params => $c->req->parameters,
-      action => $c->uri_for($c->action, $c->req->captures ),
-   );
-   $c->stash( template => 'book/form.tt', form => $result );
-   return unless $result->validated;
-   $c->res->redirect( $c->uri_for('list') );
-}
-
-sub delete : Chained('item') PathPart('delete') Args(0)
-{
-   my ( $self, $c ) = @_;
-
-   $c->stash->{book}->delete;
-   $c->res->redirect( $c->uri_for('list') );
-}
-
-sub view : Chained('item') PathPart('') Args(0)
-{
-   my ( $self, $c, $id ) = @_;
-
-   $c->stash( form => $self->view_form, template => 'book/view.tt' );
-   return unless $self->view_form->process( item => $c->stash->{book},
-      params => $c->req->parameters  );
-   $c->stash->{message} = 'Book checked out';
-}
-
-sub do_return : Chained('item') PathPart('return') Args(0)
-{
-   my ( $self, $c ) = @_;
-
-   my $book = $c->stash->{book};
-   $book->borrowed(undef);
-   $book->borrower(undef);
-   $book->update;
-
-   $c->res->redirect( '/book/' . $book->id );
-   $c->detach;
-}
-
-=back
-
-=head1 AUTHOR
-
-Gerda Shank
-
-=head1 LICENSE
-
-This library is free software . You can redistribute it and/or modify
-it under the same terms as perl itself.
-
-=cut
-
-1;
@@ -1,109 +0,0 @@
-package BookDB::Controller::Borrower;
-
-use Moose;
-BEGIN {
-   extends 'Catalyst::Controller';
-}
-
-use BookDB::Form::Borrower;
-has 'my_form' => ( isa => 'BookDB::Form::Borrower', is => 'rw',
-   lazy => 1, default => sub { BookDB::Form::Borrower->new } );
-
-=head1 NAME
-
-BookDB::Controller::Borrower
-
-=head1 DESCRIPTION
-
-Controller for Borrower
-
-=cut
-
-
-sub borrower_base : Chained PathPart('borrower') CaptureArgs(0)
-{
-   my ( $self, $c ) = @_;
-}
-
-sub default : Chained('borrower_base') PathPart('') Args
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub list : Chained('borrower_base') PathPart('list') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub do_list
-{
-   my ( $self, $c ) = @_;
-
-   my $borrowers = [ $c->model('DB::Borrower')->all ];
-   my @columns = ( 'name', 'email' );
-   $c->stash( borrowers => $borrowers, columns => \@columns,
-              template => 'borrower/list.tt' );
-}
-
-sub add : Chained('borrower_base') PathPart('add') Args(0)
-{
-   my ( $self, $c ) = @_;
-   # Create the empty borrower row for the form
-   $c->stash( borrower => $c->model('DB::Borrower')->new_result({}) );
-   return $self->form($c);
-}
-
-sub item : Chained('borrower_base') PathPart('') CaptureArgs(1)
-{
-   my ( $self, $c, $borrower_id ) = @_;
-   $c->stash( borrower => $c->model('DB::Borrower')->find($borrower_id) );
-}
-
-sub edit : Chained('item') PathPart('edit') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->form($c);
-}
-
-sub form
-{
-   my ( $self, $c ) = @_;
-
-   $c->stash( form => $self->my_form, template => 'borrower/form.tt',
-      action => $c->uri_for($c->action, $c->req->captures ));
-   return unless $self->my_form->process( item => $c->stash->{borrower},
-      params => $c->req->parameters );
-   $c->res->redirect( $c->uri_for($self->action_for('list')) );
-}
-
-sub delete : Chained('item') PathPart('delete') Args(0)
-{
-   my ( $self, $c ) = @_;
-
-   $c->stash->{borrower}->delete;
-   $c->res->redirect( $c->uri_for($c->action_for('list')) );
-}
-
-sub view : Chained('item') PathPart('') Args(0)
-{
-   my ( $self, $c, $id ) = @_;
-
-   my @columns = ( 'name', 'email', 'phone', 'url', 'active' );
-   $c->stash( columns => \@columns, template => 'borrower/view.tt' );
-}
-
-
-=head1 AUTHOR
-
-Gerda Shank
-
-=head1 LICENSE
-
-This library is free software . You can redistribute it and/or modify
-it under the same terms as perl itself.
-
-=cut
-
-1;
@@ -1,50 +0,0 @@
-package BookDB::Controller::Root;
-
-use strict;
-use warnings;
-use base 'Catalyst::Controller';
-
-#
-# Sets the actions in this controller to be registered with no prefix
-# so they function identically to actions created in MyApp.pm
-#
-__PACKAGE__->config->{namespace} = '';
-
-sub index : Path Args
-{
-   my ( $self, $c ) = @_;
-   $c->res->redirect('/book');
-   $c->detach;
-
-}
-
-=head1 NAME
-
-MyApp::Controller::Root - Root Controller for MyApp
-
-=head1 DESCRIPTION
-
-[enter your description here]
-
-=head1 METHODS
-
-=head2 end
-
-Attempt to render a view, if needed.
-
-=cut
-
-sub end : ActionClass('RenderView') { }
-
-=head1 AUTHOR
-
-Gerda Shank
-
-=head1 LICENSE
-
-This library is free software, you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-1;
@@ -1,110 +0,0 @@
-package BookDB::Controller::User;
-
-use Moose;
-BEGIN {
-   extends 'Catalyst::Controller';
-}
-
-use BookDB::Form::User;
-
-has 'user_form' => ( isa => 'BookDB::Form::User', is => 'rw',
-   lazy => 1, default => sub { BookDB::Form::User->new } );
-
-=head1 NAME
-
-BookDB::Controller::User
-
-=head1 SYNOPSIS
-
-An example of a non-database form
-
-=head1 DESCRIPTION
-
-User Controller
-
-=cut
-
-
-sub user_base : Chained PathPart('user') CaptureArgs(0)
-{
-   my ( $self, $c ) = @_;
-}
-
-sub default : Chained('user_base') PathPart('') Args
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub list : Chained('user_base') PathPart('list') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->do_list($c);
-}
-
-sub do_list
-{
-   my ( $self, $c ) = @_;
-
-   my $users = $c->model('DB::User');
-   $c->stash( users => $users, template => 'user/list.tt' );
-}
-
-sub create : Chained('user_base') PathPart('create') Args(0)
-{
-   my ( $self, $c ) = @_;
-   # Create the empty user row for the form
-   $c->stash( user => $c->model('DB::User')->new_result({}) );
-   return $self->form($c);
-}
-
-sub item : Chained('user_base') PathPart('') CaptureArgs(1)
-{
-   my ( $self, $c, $user_id ) = @_;
-   $c->stash( user => $c->model('DB::User')->find($user_id) );
-}
-
-sub edit : Chained('item') PathPart('edit') Args(0)
-{
-   my ( $self, $c ) = @_;
-   return $self->form($c);
-}
-
-sub form
-{
-   my ( $self, $c ) = @_;
-
-   my $user = $c->stash->{user};
-   $c->stash( form => $self->user_form, template => 'user/form.tt' );
-   $self->user_form->process( item => $user,
-      params => $c->req->parameters );
-   return unless $self->user_form->validated;
-   my $result = $self->user_form->values;
-   $c->res->redirect( $c->uri_for_action('/user/view', [$user->id]) );
-}
-
-sub delete : Chained('item') PathPart('delete') Args(0)
-{
-   my ( $self, $c ) = @_;
-
-   $c->stash->{user}->delete;
-   $c->res->redirect( $c->uri_for('list') );
-}
-
-sub view : Chained('item') PathPart('') Args(0) { }
-
-
-=back
-
-=head1 AUTHOR
-
-Gerda Shank
-
-=head1 LICENSE
-
-This library is free software . You can redistribute it and/or modify
-it under the same terms as perl itself.
-
-=cut
-
-1;
@@ -2,7 +2,6 @@ package BookDB::Form::Book;
 
 use HTML::FormHandler::Moose;
 extends 'HTML::FormHandler::Model::DBIC';
-with 'HTML::FormHandler::Render::Simple';
 
 =head1 NAME
 
@@ -32,6 +31,7 @@ has_field 'title' => (
 has_field 'authors' => (
     type  => 'Multiple',
     label => 'Authors',
+    label_column => 'full_name',
     order => '2',
 );
 
@@ -79,6 +79,11 @@ has_field 'comment' => (
     order => 9,
 );
 
+has_field 'borrower' => (
+    type => 'Select',
+    label_column => 'name_email',
+);
+
 has_field submit => ( type => 'Submit', value => 'Update' );
 
 sub validate_year {
@@ -0,0 +1,75 @@
+package BookDB::Form::Book2PK;
+use HTML::FormHandler::Moose;
+extends 'HTML::FormHandler::Model::DBIC';
+
+with 'HTML::FormHandler::Widget::Theme::Bootstrap';
+
+=head1 NAME
+
+Form object for the Book Controller
+
+=head1 SYNOPSIS
+
+Form used for book/add and book/edit actions
+
+=head1 DESCRIPTION
+
+Catalyst Form.
+
+=cut
+
+has '+item_class'        => ( default => 'Book2PK' );
+
+has_field 'title' => (
+    type             => 'Text',
+    required         => 1,
+    required_message => 'A book must have a title.',
+    label            => 'Title',
+);
+
+has_field 'publisher' => (
+    type  => 'Text',
+    label => 'Publisher',
+);
+
+# has_many relationship pointing to mapping table
+has_field 'isbn' => (
+    type     => 'Text',
+    label    => 'ISBN',
+    unique   => 1,
+    required => 1,
+);
+has_field 'year' => (
+    type        => 'Integer',
+    range_start => '1900',
+    range_end   => '2020',
+    label       => 'Year',
+    required    => 1,
+);
+has_field 'pages' => (
+    type  => 'Integer',
+    label => 'Pages',
+);
+
+has_field submit => ( type => 'Submit', value => 'Update', element_class => ['btn'] );
+
+sub validate_year {
+    my ( $self, $field ) = @_;
+    $field->add_error('Invalid year')
+      if ( ( $field->value > 3000 ) || ( $field->value < 1600 ) );
+}
+
+=head1 AUTHOR
+
+Gerda Shank
+
+=head1 LICENSE AND COPYRIGHT
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself. See L<perlartistic>.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+no HTML::FormHandler::Moose;
+1;
@@ -3,9 +3,6 @@
 
     use HTML::FormHandler::Moose;
     extends 'HTML::FormHandler::Field::Compound';
-#    with 'HTML::FormHandler::Model::DBIC';
-
-#    has '+item_class' => ( default => 'User' );
 
     has_field 'user_name';
     has_field 'fav_cat' => ( label => 'Favorite Book Category' );
@@ -2,8 +2,6 @@ package BookDB::Form::Borrower;
 
 use HTML::FormHandler::Moose;
 extends 'HTML::FormHandler::Model::DBIC';
-with 'HTML::FormHandler::Render::Simple';
-
 
 =head1 NAME
 
@@ -2,7 +2,6 @@ package BookDB::Form::BorrowerX;
 
 use Moose;
 extends 'HTML::FormHandler::Model::DBIC';
-with 'HTML::FormHandler::Render::Simple';
 
 =head1 NAME
 
@@ -2,7 +2,6 @@ package BookDB::Form::User;
 
 use HTML::FormHandler::Moose;
 extends 'HTML::FormHandler::Model::DBIC';
-with 'HTML::FormHandler::Render::Simple';
 use DateTime;
 
 has '+item_class' => ( default => 'User');
@@ -1,36 +0,0 @@
-package BookDB::Model::DB;
-
-use strict;
-use base 'Catalyst::Model::DBIC::Schema';
-
-__PACKAGE__->config(
-    schema_class => 'BookDB::Schema',
-    connect_info => [
-        'dbi:SQLite:t/db/book.db',
-
-    ],
-);
-
-=head1 NAME
-
-BookDB::Model::DB - Catalyst DBIC Schema Model
-=head1 SYNOPSIS
-
-See L<BookDB>
-
-=head1 DESCRIPTION
-
-L<Catalyst::Model::DBIC::Schema> Model using schema L<BookDB::Schema::DB>
-
-=head1 AUTHOR
-
-Gerda Shank
-
-=head1 LICENSE
-
-This library is free software, you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-1;
@@ -40,7 +40,7 @@ __PACKAGE__->many_to_many(
    'books' => 'author_books', 'book'
 );
 
-sub name {
+sub full_name {
     my $self = shift;
     return $self->first_name . " " . $self->last_name;
 }
@@ -0,0 +1,31 @@
+package BookDB::Schema::Result::Book2PK;
+
+use Moose;
+use MIME::Base64;
+
+use base 'DBIx::Class';
+
+__PACKAGE__->load_components("Core");
+__PACKAGE__->table("book2pk");
+__PACKAGE__->add_columns(
+  "libraryid",
+  { data_type => "INTEGER", is_nullable => 0, default_value => 1, size => undef },
+  "id",
+  { data_type => "INTEGER", is_nullable => 0, size => undef },
+  "isbn",
+  { data_type => "varchar", is_nullable => 0, size => 100 },
+  "title",
+  { data_type => "varchar", is_nullable => 0, size => 100,
+    extra => { field_def => { type => 'TextArea', size => '64', temp => 'testing' } },
+  },
+  "publisher",
+  { data_type => "varchar", is_nullable => 0, size => 100 },
+  "pages",
+  { data_type => "INTEGER", is_nullable => 0, size => undef },
+  "year",
+  { data_type => "INTEGER", is_nullable => 0, size => undef },
+);
+__PACKAGE__->set_primary_key("libraryid", "id");
+__PACKAGE__->add_unique_constraint( 'isbn' => ['libraryid', 'isbn'] );
+
+1;
@@ -28,5 +28,10 @@ __PACKAGE__->has_many(
   { "foreign.borrower" => "self.id" },
 );
 
+sub name_email {
+    my $self = shift;
+    return $self->name . " <" . $self->email . ">";
+}
+
 
 1;
@@ -1,37 +0,0 @@
-package BookDB::View::TT;
-
-use strict;
-use base 'Catalyst::View::TT';
-
-=head1 NAME
-
-BookDB::V::TT - TT View Component
-
-=head1 SYNOPSIS
-
-See L<BookDB>
-
-=head1 DESCRIPTION
-
-TT View Component.
-
-=cut
-
-BookDB::View::TT->config({
-    TEMPLATE_EXTENSION => '.tt',
-    INCLUDE => [ BookDB->path_to('root') ],
-});
-
-
-=head1 AUTHOR
-
-Gerda Shank
-
-=head1 LICENSE
-
-This library is free software . You can redistribute it and/or modify
-it under the same terms as perl itself.
-
-=cut
-
-1;
@@ -1,27 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-<p>[% message %]</p>
-[% FOR efield IN form.error_fields %]
-<div class='error' id=error>[% efield.errors %] </div>
-[% END %]
-<form action="[% action %]" method="post">
-   [% form.field('title').render %]
-
-   [% form.field('authors').render %]
-
-   [% form.field('genres').render %]
-
-   [% form.field('publisher').render %]
-
-   [% form.field('isbn').render %]
-
-   [% form.field('format').render %]
-
-   [% form.field('pages').render %]
-
-   [% form.field('year').render %]
-
-   [% form.field('submit').render %]
-<form/>
-<p><a class="big" href="[% c.uri_for('list') %]">&gt; LIST</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,25 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-<table id="books" cellspacing="0" summary="The list of all books">
-<caption>Table: List of Books</caption>
-  <tr>
-    [% FOR column IN columns %]
-    <th scope="col">[% column %]</th>
-    [% END %]
-    <th/>
-    [% counter = 0 %]
-  </tr>
-  [% FOR book IN books %]
-  <tr[% IF (counter % 2) == 0 %] class="alt"[% END %]>
-    [% FOR column IN columns %]
-    <td>[% book.$column %]</td>
-    [% END %]
-    <td>
-      <a href="[% '/book/' _ book.id  %]">View</a>
-      <a href="[% '/book/' _ book.id _ '/edit' %]">Edit</a>
-      <a href="[% '/book/' _ book.id _ '/delete' %]">Delete</a>
-    </td>[% counter = counter + 1 %]
-  </tr>[% END %]
-</table>
-<p><a class="big" href="[% '/book/create' %]">+ ADD</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,67 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-
-<p>[% message %]</p>
-[% FOR field IN form.error_fields %]
-<div class='error' id=error>[% field.name _ ': ' _ field.errors %] </div>
-[% END %]
-   <p>
-    <b class="title">Title:</b>
-    <p>[% form.item.title %]</p>
-   </p>
-   <p>
-    <b class="title">Author:</b>
-    <p>[% form.item.author %]</p>
-   </p>
-   <p>
-    <b class="title">Genres:</b>
-    [% FOR genre IN form.item.genres %]
-    <p>[% genre.name %]</p>
-    [% END %]
-   </p>
-   <p>
-    <b class="title">Publisher:</b>
-    <p>[% form.item.publisher %]</p>
-   </p>
-   <p>
-    <b class="title">ISBN:</b>
-    <p>[% form.item.isbn %]</p>
-   </p>
-   <p>
-    <b class="title">Format:</b>
-    <p>[% form.item.format.name %]</p>
-   </p>
-   <p>
-    <b class="title">Pages:</b>
-    <p>[% form.item.pages %]</p>
-   </p>
-   <p>
-    <b class="title">Year:</b>
-    <p>[% form.item.year %]</p>
-   </p>
-<br />
-[% IF form.item.borrower %]
-Checked out to <a href="[%base _ 'borrower/view/' _ form.item.borrower.id%]">[%form.item.borrower.name%]</a> ([%form.item.borrowed%])<br/>
-<a href="[% form.item_id _ '/return' %]">Return it</a>
-[%ELSE%]
-<form action="[% c.chained_uri_for %]" method="post">
-   <p>
-   [% SET f = form.field('borrower') %]
-   <label class="label" for="[% f.name %]">Not borrowed.</label>
-   <br />
-   <input type="submit" value="Check out to"/>
-   <select name="[% f.name %]">
-     [% FOR option IN f.options %]
-       <option value="[% option.value %]" [% IF option.value == f.fif %]selected="selected"[% END %]>[% option.label %]</option>
-     [% END %]
-   </select>
-   <p>
-   [% SET f = form.field('borrowed') %]
-     <input  type="hidden" name="[% f.name %]" id="[% f.name %]" value="[% f.fif %]">
-   </p>
-   </p>
-</form>
-[%END%]
-
-<p><a class="big" href="[% c.uri_for('list') %]">&gt; LIST</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,14 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-
-<p>[%message%]</p>
-[% FOR field IN form.error_fields %]
-  [% FOR error IN field.errors %]
-    <div class='error' id=error>[% error %] </div>
-  [% END %]
-[% END %]
-
-[% form.render %]
-
-<p><a class="big" href="[% c.uri_for('list') %]">&gt; LIST</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,23 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-<table id="borrowers">
-<caption>Table: List of Borrowers</caption>
-  <tr>
-    [% FOR column IN columns %]
-      <th>[% column %]</th>
-    [% END %]
-    <th/>[% counter = 0 %]
-  </tr>[% FOR borrower IN borrowers %]
-  <tr[% IF (counter % 2) == 0 %] class="alt"[% END %]>
-    [% FOR column IN columns %]
-      <td>[% borrower.$column %]</td>
-    [% END %]
-    <td>
-      <a href="[% '/borrower/' _ borrower.id %]">View</a>
-      <a href="[% '/borrower/' _ borrower.id _ '/edit' %]">Edit</a>
-      <a href="[% '/borrower/' _ borrower.id _ '/delete' %]">Destroy</a>
-    </td>[% counter = counter + 1 %]
-  </tr>[% END %]
-</table>
-<p><a class="big" href="/borrower/add">+ ADD</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,24 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-
-[% FOR column IN columns %]
-    <b class="title">[% column %]</b><br/>
-    [% borrower.$column %]<br/><br/>
-[% END %]
-<table>
-    <tr>
-      <th>Book</th><th>Borrowed</th>
-      <th/>
-    </tr>
-[% FOR book IN borrower.books %]
-    <tr>
-      <td>[%book.title%]</td>
-      <td>[%book.borrowed%]</td>
-      <td><a href="[% '/book/' _ book.id %]">View</a>
-          <a href="[% '/book/' _ book.id _ '/return' %]">Return</a></td>
-    </tr>
-[% END %]
-</table>
-
-<p><a class="big" href="[% c.uri_for('list') %]">&gt; LIST</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,2 +0,0 @@
-</body>
-</html>
@@ -1,11 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>BookDB</title>
-<link href="[% c.uri_for('/scaffold/styles.css') %]" rel="stylesheet" type="text/css" />
-</head>
-
-<body>
-[% PROCESS scaffold/nav.tt %]
diff --git a/var/tmp/source/GSHANK/HTML-FormHandler-Model-DBIC-0.19/HTML-FormHandler-Model-DBIC-0.19/t/lib/BookDB/root/scaffold/header_bg.jpg b/var/tmp/source/GSHANK/HTML-FormHandler-Model-DBIC-0.19/HTML-FormHandler-Model-DBIC-0.19/t/lib/BookDB/root/scaffold/header_bg.jpg
deleted file mode 100644
index 36c9df5d..00000000
Binary files a/var/tmp/source/GSHANK/HTML-FormHandler-Model-DBIC-0.19/HTML-FormHandler-Model-DBIC-0.19/t/lib/BookDB/root/scaffold/header_bg.jpg and /dev/null differ
@@ -1,8 +0,0 @@
-<ul>
-  <li class="section">Books</li>
-  <li><a href="/book/create">Add</a></li>
-  <li><a href="/book/list">List</a></li>
-  <li class="section">Borrowers</li>
-  <li><a href="/borrower/add">Add</a></li>
-  <li><a href="/borrower/list">List</a></li>
-</ul>
@@ -1,113 +0,0 @@
-body {
-    font: normal 11px auto Verdana, Arial, Helvetica, sans-serif;
-    color: #4f6b72;
-    background: #E6EAE9;
-}
-
-a { color: #c75f3e; }
-
-a:hover {
-    background-color: #c75f3e;
-    color: #FFF;
-}
-
-/*
-#books {
-    width: 700px;
-    padding: 0;
-    margin: 0;
-}
-*/
-
-label {
-    float: left;
-    width: 70px;
-}
-
-.title {
-    text-transform: uppercase;
-    text-decoration: underline;
-}
-
-ul { padding: 0; }
-
-li {
-    display: inline;
-    font: bold 11px Verdana, Arial, Helvetica, sans-serif;
-    color: #4f6b72;
-    border: 1px solid #C1DAD7;
-    letter-spacing: 2px;
-    text-transform: uppercase;
-    padding: 6px 6px 6px 12px;
-    background-color: #FFF;
-}
-
-.section { display: }
-
-caption {
-    padding: 0 0 5px 0;
-    width: 700px;
-    font: italic 11px Verdana, Arial, Helvetica, sans-serif;
-    text-align: left;
-}
-
-th {
-    font: bold 11px Verdana, Arial, Helvetica, sans-serif;
-    color: #4f6b72;
-    border-right: 1px solid #C1DAD7;
-    border-bottom: 1px solid #C1DAD7;
-    border-top: 1px solid #C1DAD7;
-    letter-spacing: 2px;
-    text-transform: uppercase;
-    text-align: left;
-    padding: 6px 6px 6px 12px;
-    background: #CAE8EA url(header_bg.jpg) no-repeat;
-}
-
-th.nobg {
-    border-top: 0;
-    border-left: 0;
-    border-right: 1px solid #C1DAD7;
-    background: none;
-}
-
-td {
-    border-right: 1px solid #C1DAD7;
-    border-bottom: 1px solid #C1DAD7;
-    padding: 6px 6px 6px 12px;
-    color: #4f6b72;
-}
-
-tr {
-    background-color: #D2EBEB;
-    color: #797268;
-}
-
-tr.alt {
-    background: #FFF;
-    color: #797268;
-}
-
-th.spec {
-    border-left: 1px solid #C1DAD7;
-    border-top: 0;
-    background: #FFF;
-    font: bold 10px Verdana, Arial, Helvetica, sans-serif;
-}
-
-th.specalt {
-    border-left: 1px solid #C1DAD7;
-    border-top: 0;
-    background-color: #f5fafa;
-    font: bold 10px Verdana, Arial, Helvetica, sans-serif;
-    color: #797268;
-}
-
-.error {
-    font: bold 14px Verdana, Arial, Helvetica, sans-serif;
-    font-size: 2em;
-    color: #4f6b72;
-    border: 1px solid: #797268
- }
-
-.big { font-weight:bold; font-size: 16px; }
@@ -1,29 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-<p>[% message %]</p>
-[% FOR efield IN form.error_fields %]
-<div class='error' id=error>[% efield.errors %] </div>
-[% END %]
-<form action="[% c.uri_for_action('/user/edit', [user.id]) %]" method="post">
-
-  [% form.render_field('user_name') %]
-  [% form.render_field('fav_cat') %]
-  [% form.render_field('occupation') %]
-  [% form.render_field('country') %]
-  [% form.render_field('license') %]
-  [% form.render_field('opt_in') %]
-  [% form.render_field('birthdate') %]
-<p>Employer</p>
-  [% form.render_field('employers') %]
-<p>Addresses</p>
-[% FOR ifield IN form.field('addresses').fields %]
-   <div>
-     [% form.render_field( ifield ) %]
-   </div>
-[% END %]
-
-
-   <input type="submit" value="Save"/>
-<form/>
-<p><a class="big" href="[% c.uri_for('list') %]">&gt; LIST</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,25 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-<table id="books" cellspacing="0" summary="The list of all books">
-<caption>Table: List of Users</caption>
-  <tr>
-    [% FOR column IN users.result_source.columns %]
-    <th scope="col">[% column %]</th>
-    [% END %]
-    <th/>
-    [% counter = 0 %]
-  </tr>
-  [% WHILE (user = users.next) %]
-  <tr[% IF (counter % 2) == 0 %] class="alt"[% END %]>
-    [% FOR column IN users.result_source.columns %]
-    <td>[% user.$column %]</td>
-    [% END %]
-    <td>
-      <a href="[% '/user/' _ user.id  %]">View</a>
-      <a href="[% '/user/' _ user.id _ '/edit' %]">Edit</a>
-      <a href="[% '/user/' _ user.id _ '/delete' %]">Delete</a>
-    </td>[% counter = counter + 1 %]
-  </tr>[% END %]
-</table>
-<p><a class="big" href="[% '/user/create' %]">+ ADD</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1,16 +0,0 @@
-[% PROCESS scaffold/header.tt %]
-
-<p>[% message %]</p>
-[% FOR field IN form.error_fields %]
-<div class='error' id=error>[% field.name _ ': ' _ field.errors %] </div>
-[% END %]
-
-[% FOR col IN user.columns %]
-   <p>
-    <b class="[% col %]">[% col %]</b>
-    <p>[% user.$col %]</p>
-   </p>
-[% END %]
-<p><a class="big" href="[% c.uri_for('list') %]">&gt; LIST</a></p>
-
-[% PROCESS scaffold/footer.tt %]
@@ -1 +0,0 @@
-<input type="checkbox" name="[% f.name %]" value="[% f.name %]" [% IF f.fif %]selected="selected"[% END %]>
@@ -1,9 +0,0 @@
-<label class="label [% IF field.has_errors %]fld_error[% END %]" for="[% f.name %]">[% f.label %]</label>
-[% FOR option IN f.options %]
- <input type="radio" value="[% option.value %]"
- [% FOREACH selval IN f.fif %]
-   [% IF selval == option.value %]selected="selected"[% END %]
- [% END %]>
- [% option.label | html %]>
-[% END %]
-
@@ -1 +0,0 @@
-</form>
@@ -1,2 +0,0 @@
-<form name="[% form.name %]" method="post" action="[% c.uri_for( form.action ) %]">
-
@@ -1,11 +0,0 @@
-<label class="label [% IF field.has_errors %]fld_error[% END %]" for="[% f.name %]">[% f.label %]</label>
-<select name="[% f.name %]" multiple="multiple" size="[% f.size %]">
-  [% FOR option IN f.options %]
-    <option value="[% option.value %]"
-    [% FOREACH selval IN f.fif %]
-      [% IF selval == option.value %]selected="selected"[% END %]
-    [% END %]>
-    [% option.label | html %]</option>
-  [% END %]
-</select>
-
@@ -1,7 +0,0 @@
-<label class="label [% IF f.has_errors %]fld_error[% END %]" for="[% f.name %]">[% f.label %]</label>
-[% FOR option IN f.options %]
- <input type="radio" value="[% option.label %]"
- [% IF option.value == f.fif %] selected="selected"[% END %]>
- [% option.label | html %]>
-[% END %]
-
@@ -1,9 +0,0 @@
-<label class="label [% IF f.has_errors %]fld_error[% END %]" for="[% f.name %]">[% f.label %]</label>
-<select name="[% f.name %]">
-  [% FOR option IN f.options %]
-    <option value="[% option.value %]"
-    [% IF option.value == f.fif %]selected="selected"[% END %]>
-    [% option.label | html %]</option>
-  [% END %]
-</select>
-
@@ -1,3 +0,0 @@
-<label class="label [% IF f.has_errors %]fld_error[% END %]" for="[% f.name %]">[% f.label %]</label>
-<input type="text" name="[% f.name %]" id="[% f.name %]" value="[% f.fif %]">
-
@@ -1,4 +0,0 @@
-<label class="label [% IF f.has_errors %]fld_error[% END %]" for="[% f.name %]">[% f.label %]</label>
-<textarea rows="[% f.rows %]" cols="[% f.cols %]">
-[% f.fif %]
-</textarea>
@@ -85,6 +85,7 @@ my $params = {
 };
 
 $form3->process( params => $params );
+$book3 = $form3->item;
 is( $book3->publisher, 'S.Else', 'row object updated');
 is( $form3->field('extra')->value, 'extra_test', 'value of non-db field');
 ok( $form3->item->id, 'get id from new result');
@@ -37,4 +37,8 @@ $form = BookDB::Form::AuthorOld->new(item_id => $pk_hashlist, schema => $schema)
 ok( $form, 'get form with array of hashref primary key' );
 is( $form->item->country_iso, 'GB', 'got right row');
 
+$form = BookDB::Form::AuthorOld->new( item => $author );
+ok( $form, 'got form with only item passed in' );
+is_deeply( $form->item_id, $pk_hashlist, 'got primary key' );
+
 done_testing;
@@ -75,7 +75,11 @@ my $params = {
    'birthdate.day' => 21,
    'employers.0.name' => "Acme Software",
    'employers.0.category' => "Computers",
-   'employers.0.country' => "United Kingdom"
+   'employers.0.country' => "United Kingdom",
+   'addresses.0.address_id' => '',
+   'addresses.0.city' => '',
+   'addresses.0.country' => '',
+   'addresses.0.street' => '',
 };
 $form->process( item_id => undef, params => $params);
 my $new_user = $form->item;
@@ -8,9 +8,20 @@ BEGIN {
 
 use strict;
 use warnings;
-use Test::More;
 
-eval 'use Test::NoTabs';
-plan skip_all => 'Test::NoTabs required' if $@;
+# this test was generated with Dist::Zilla::Plugin::NoTabsTests 0.05
 
-all_perl_files_ok();
+use Test::More 0.88;
+use Test::NoTabs;
+
+my @files = (
+    'lib/HTML/FormHandler/Generator/DBIC.pm',
+    'lib/HTML/FormHandler/Model/DBIC.pm',
+    'lib/HTML/FormHandler/Model/DBIC/TypeMap.pm',
+    'lib/HTML/FormHandler/TraitFor/DBICFields.pm',
+    'lib/HTML/FormHandler/TraitFor/Model/DBIC.pm',
+    'script/form_generator.pl'
+);
+
+notabs_ok($_) foreach @files;
+done_testing;
@@ -1,17 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-use warnings;
-
-use lib ('t/lib');
-use BookDB::Schema;
-
-use DBIx::Class::Schema::Loader ('make_schema_at');
-make_schema_at(
-    'BookDB::Schema',
-    {
-        debug          => 1,
-        dump_directory => './lib',
-    },
-    [ 'dbi:SLite:t/db/book.db' ],
-);
-
@@ -1,60 +0,0 @@
-#!/usr/bin/env perl
-
-BEGIN {
-    $ENV{CATALYST_SCRIPT_GEN} = 40;
-}
-
-use Catalyst::ScriptRunner;
-Catalyst::ScriptRunner->run('BookDB', 'Server');
-
-1;
-
-=head1 NAME
-
-bookdb_server.pl - Catalyst Test Server
-
-=head1 SYNOPSIS
-
-bookdb_server.pl [options]
-
-   -d --debug           force debug mode
-   -f --fork            handle each request in a new process
-                        (defaults to false)
-   -? --help            display this help and exits
-   -h --host            host (defaults to all)
-   -p --port            port (defaults to 3000)
-   -k --keepalive       enable keep-alive connections
-   -r --restart         restart when files get modified
-                        (defaults to false)
-   -rd --restart_delay  delay between file checks
-                        (ignored if you have Linux::Inotify2 installed)
-   -rr --restart_regex  regex match files that trigger
-                        a restart when modified
-                        (defaults to '\.yml$|\.yaml$|\.conf|\.pm$')
-   --restart_directory  the directory to search for
-                        modified files, can be set mulitple times
-                        (defaults to '[SCRIPT_DIR]/..')
-   --follow_symlinks    follow symlinks in search directories
-                        (defaults to false. this is a no-op on Win32)
-   --background         run the process in the background
-   --pidfile            specify filename for pid file
-
- See also:
-   perldoc Catalyst::Manual
-   perldoc Catalyst::Manual::Intro
-
-=head1 DESCRIPTION
-
-Run a Catalyst Testserver for this application.
-
-=head1 AUTHORS
-
-Catalyst Contributors, see Catalyst.pm
-
-=head1 COPYRIGHT
-
-This library is free software. You can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
@@ -1,40 +0,0 @@
-#!/usr/local/bin/perl -w
-
-use Catalyst::ScriptRunner;
-Catalyst::ScriptRunner->run('BookDB', 'Test');
-
-1;
-
-=head1 NAME
-
-bookdb_test.pl - Catalyst Test
-
-=head1 SYNOPSIS
-
-bookdb_test.pl [options] uri
-
- Options:
-   --help    display this help and exits
-
- Examples:
-   bookdb_test.pl http://localhost/some_action
-   bookdb_test.pl /some_action
-
- See also:
-   perldoc Catalyst::Manual
-   perldoc Catalyst::Manual::Intro
-
-=head1 DESCRIPTION
-
-Run a Catalyst action from the command line.
-
-=head1 AUTHORS
-
-Catalyst Contributors, see Catalyst.pm
-
-=head1 COPYRIGHT
-
-This library is free software. You can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
@@ -45,7 +45,7 @@ is( $error, 'Duplicate value for ISBN', 'error message for duplicate');
             isbn => {
                type => 'Text',
                unique => 1,
-               unique_message => 'Duplicate ISBN number',
+               messages => { unique => 'Duplicate ISBN number' },
             }
         ]
    }
@@ -59,4 +59,10 @@ ok( ! $form2->process( $params ), 'duplicate isbn again' );
 
 is( $errors[0], 'Duplicate ISBN number', 'field error message for duplicate');
 
+# Tests for fields that are inactive
+my $item = $schema->resultset('Book')->new({});
+ok ( $form->process( item => $item, params => $params, inactive => ['isbn'] ),
+    'no uniqueness check on inactive fields' );
+$item->delete if $item->in_storage; # Cleanup insert
+
 done_testing;