remaing todo on DBIC glue stuff

-- delete control
-- review that we are doing nesting rules right over in set_single_related_from_params
-- make final descioun about allows lookups via single type relationships (flag or not)
-- do a review to see where we are doing the same query over and over
- version 2 of view helpers based on the proposed view metadata code
-- Make a more complet example application to make sure its all looking good


nesting notes

If the request only containers PKs OR unique keys (only one of them) then we ignore nesting
roles for the target table and instead restrict to lookups only.

belongs_to
  Generally this type of relationship is used for lookup tables (such as states, countries, etc) so
  those are usually fixed values the target table (changing those are generally an admin function).
  However its not impossible for

  - If the FK is present then update based on FK
  - If 'update_only' then always update any existing
  - does not allow nesting to create or update  only find  
  - find by FK or unique key  is allowed

has_one, might have
  - if PK is present then always update
  - if 'update_only' is present then always update, PK or not, unless there's no record, in which case create
  - otherwise (if no PK and no 'update_only') then always delete and create a new record

has_many
  - if PK is present than find and update or die not found
  - if both PK is present and _delete key in request then delete matching record (or die if none are found)
  - IF no PK create a new record
  * records unmentioned in the request are not changed or deleted UNLESS atomic_set is true.

  


  {

    role_pks => [
      { id => 1 },
      { id => 2 }
    ]
  }


package Local::User;

use Moose;
use Valiant::Validations;
use Valiant::Nested;  # applies Valiant::Nestable

has profile => (
  is => 'ro',
  accepts_nested => '::Profile',
  validations => [ Object=>1 ]
);

has credit_cards => (
  is => 'ro',
  nested => 'CreditCard[]',   # isa  => Local::CreditCard  with coerce on hash over array    ArrayRef[HashRef]
);

accept_nested_for 'credit_cards', 
  type => 'Local::CreditCard', # or 'CreditCard[]' for simple array
  array => 1,  # or +{ limit => Int||Coderef }
  reject_if => sub { my ($self, $value) = @_; ... }, # When array is applied to each item in array, if not just on the entire value
  coerce_via => sub { my ($self, $value) = @_;  ... },  
;

validates 'credit_cards', Array => +{ validations=>1, max_length=>10 };  # you need to be explicit if you want the validations aggregated

========

++ Common

Assumptions:
  -- PKs are always autoinc or autonextval.   If you are setting PK via a DBIC not everything mifght work as expected

accept_nested_for *, +{ 
  reject_if => sub { my ($row, $params) = @_ }
  limit => Int|CodeRef
  allow_destroy => Bool|CodeRef
};

++ has_one, might_have

When the PK is  is_auto_increment|auto_nextval => 1 and always_update => 0

-- If parameters doesn't have PK then always create (and issue a delete for an existing one if there is one)
-- If parameters do have PK then always update ( die if the PK isn't found)

When the PK is is_auto_increment|auto_nextval => 1 and always_update => 1

-- If a row exists update it whether or not the PK is in params
-- If the row doesn't exist then create it

When allow_destroy => 1 and always_update => 0

-- If the PK is in params, then destroy it when _destroy=1 is in params
-- if _destroy=>1 is in params but PK is not in params then issue an exception
-- If the PK wasn't in the DB its a not an exception to issue a pointless destroy

When allow_destroy => 1 and always_update => 1

-- If _destroy is in params then always delete either the PK (if its in params) or the existing record (if one exists and PK not in params)
-- If the PK doesn't exist or the row doesn't exist and _destroy is in params just skip 

++ belongs_to

When the PK exists in params and in the DB

   -- update changed values

When the PK isn't in params BUT always_update => 1 and there is a realted record 

   -- update changed values

When the PK isn't in params and there is no existing related record

   -- create new record,

When the PK is in tbe params and allow_destroy=>1 and _destroy=>1 is in params

  -- delete the matching record if one exists

has_many

  -- If there are records in the selected cache that are not present in params (matched via the PK) then
   those records are marked for delete when allow_destroy=>1.  (??? should this be a separate flag)

  -- for each record in params:
    -- When there is a PK in Params then update the match record in the DB
    -- When there is no PK in Params then create a new record in the DB
    -- When there is a PK in Params and a _destroy=>1 in Params and allow_destroy=>1 then delete the matching records in DB

Question, should we have a flag that allows match by unique keys  (find_with_uniques => 1 | [@names_Of_keys] )

