[Jifty-commit] r5775 - Jifty-DBI/trunk/lib/Jifty/DBI
Jifty commits
jifty-commit at lists.jifty.org
Mon Sep 1 13:50:51 EDT 2008
Author: ruz
Date: Mon Sep 1 13:50:51 2008
New Revision: 5775
Modified:
Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm
Log:
* add double naming schema for record references:
** name_by - name is object accessor, name_by - value, name_by in DB
** name - name is object accessor, name_by - value, name in DB
* So it's more about column name in the DB
* as well fixed situation with 'column X_not_id refers_to M by "not_id"'
Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm (original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Schema.pm Mon Sep 1 13:50:51 2008
@@ -343,16 +343,23 @@
$refclass->require();
die $UNIVERSAL::require::ERROR if ($UNIVERSAL::require::ERROR);
}
- # References assume a refernce to an integer ID unless told otherwise
- $column->type('integer') unless ( $column->type );
-
# A one-to-one or one-to-many relationship is requested
if ( UNIVERSAL::isa( $refclass, 'Jifty::DBI::Record' ) ) {
# Assume we refer to the ID column unless told otherwise
$column->by('id') unless $column->by;
+ my $by = $column->by;
+ unless ( $column->type ) {
+ # XXX, TODO: we must set column type to the same value
+ # as column we refer to.
+ #
+ # my $referenced_column = $refclass->column( $by );
+ # $column->type( $referenced_column->type );
+ $column->type('integer');
+ }
+
# Handle *_id reference columns specially
- if ( $name =~ /(.*)_id$/ ) {
+ if ( $name =~ /(.*)_\Q$by\E$/ ) {
my $aliased_as = $1;
my $virtual_column = $from->add_column($aliased_as);
@@ -369,8 +376,23 @@
# Create the helper methods for the virtual column too
$from->_init_methods_for_column($virtual_column);
- }
+ } else {
+ my $aliased_as = $name .'_'. $by;
+ my $virtual_column = $from->add_column($aliased_as);
+
+ # Clone ourselves into the virtual column
+ %$virtual_column = %$column;
+
+ # This column is now just the ID, the virtual holds the ref
+ $virtual_column->refers_to(undef); $virtual_column->by(undef);
+ # Note the original column
+ $virtual_column->aliased_as($aliased_as);
+ $virtual_column->alias_for_column($name);
+
+ # Create the helper methods for the virtual column too
+ $from->_init_methods_for_column($virtual_column);
+ }
} elsif ( UNIVERSAL::isa( $refclass, 'Jifty::DBI::Collection' ) ) {
$column->by('id') unless $column->by;
$column->virtual('1');
@@ -434,23 +456,84 @@
=head2 references
Indicates that the column references an object or a collection of objects in another
-class. You may refer to either a class that inherits from Jifty::Record by a primary
-key in that class or to a class that inherits from Jifty::Collection.
+class. You may refer to either a class that inherits from L<Jifty::Record> by a primary
+key in that class or to a class that inherits from L<Jifty::Collection>.
+
+=head3 referencing a record
Correct usage is C<references Application::Model::OtherClass by 'column_name'>, where
-Application::Model::OtherClass is a valid Jifty model and C<'column_name'> is
-a column containing unique values in OtherClass. You can omit C<by 'column_name'> and
-the column name 'id' will be used.
-
-If you are referring to a Jifty::Collection then you must specify C<by 'column_name'>.
-
-When accessing the value in the column the actual object referenced will be returned for
-refernces to Jifty::Records and a reference to a Jifty::Collection will be returned for
-columns referring to Jifty::Collections.
-
-For columns referring to Jifty::Records you can access the actual value of the column
-instead of the object reference by appending '_id' to the column name. As a result,
-you may not end any column name which uses 'references' using '_id'.
+Application::Model::OtherClass is a valid Jifty model, subclass of L<Jifty::Record>,
+and C<'column_name'> is a distinct column of OtherClass. You can omit C<by 'column_name'>
+and the column name 'id' will be used.
+
+At this moment you must specify type of the column your self to match type of the column
+you refer to.
+
+You can name a column as combination of 'name' and 'by', for example:
+
+ column user_name => references App::Model::User by 'name', type is 'varchar(64)';
+
+Then user, user_name and respective setters will be generated. user method will return
+object, user_name will return actual value. Note that if you're using some magic on load
+for user records then to get real name of loaded record you should use C<< $record->user->name >>
+instead.
+
+In the above case name of the column in the DB will be 'user_name'. If you don't like
+suffixes like '_id', '_name' and other in the DB then you can name column without suffix,
+for example:
+
+ column user => references App::Model::User by 'name', type is 'varchar(64)';
+
+In this case name of the column in the DB will be 'user', accessors will be the same
+as in above example.
+
+=head3 referencing a collection
+
+Correct usage is C<references Application::Model::OtherCollection by 'column_name'>, where
+Application::Model::OtherCollection is a valid Jifty model, subclass of L<Jifty::Collection>,
+and C<'column_name'> is a column of records in OtherCollection. In this case C<by 'column_name'>
+is not optional.
+
+Columns that refers to a collection are virtual and can be changed. So such columns in a model
+doesn't create real columns in the DB, but instead it's way to name collection of records that
+refer to this records.
+
+=head3 example
+
+Simple model with users and multiple phone records per user:
+
+ package TestApp::Model::User;
+ use Jifty::DBI::Schema;
+ use Jifty::DBI::Record schema {
+ column name => type is 'varchar(18)';
+ ...
+ column phones => references TestApp::Model::PhoneCollection by 'user';
+ };
+
+ package TestApp::Model::Phone;
+ use Jifty::DBI::Schema;
+ use Jifty::DBI::Record schema {
+ column user => references TestApp::Model::User by 'id',
+ is mandatory;
+ column type => ...;
+ column value => ...;
+ };
+
+From a user record you get his phones and do something:
+
+ my $phones = $user->phones;
+ while ( my $phone = $phones->next ) {
+ ...
+ }
+
+From a phone record you can get its owner or change it:
+
+ my $user_object = $phone->user;
+ my $user_id = $phone->user_id;
+
+ $phone->set_user( $new_owner_object );
+ $phone->set_user( 123 ); # using id
+ $phone->set_user_id( 123 ); # the same, but only using id
=head2 refers_to
More information about the Jifty-commit
mailing list