Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread John Siracusa
On 1/30/07 11:16 PM, Jonathan Vanasco wrote:
> the consensus is clearly otherwise, but let me expand my suggestions to:
> 
> a- the name semantically notes that it doesn't alter the object
> like other rose functions

I think "find" expresses that pretty well already.

>  b- the function require a flag that the user know whats going on

I think that's overkill.  Anyone who knows about these method sat all will
have learned about them from the docs, which will explain how they work.

>  c- this be placed not in rose::db::object, but in some other
> class which extends rose::db::object ( rose::db::objectalt )

It's just a method type for a relationship.  There are already more of those
than are used by default, many of which act very differently than the
default get_set_on_save methods (e.g., add_now)
 
> i think my issue is that it functions so much like a manager call and
> not like a rose object , yet the point of it is to have the
> functionality of a manager call in the object itself.

Right, because it's cumbersome to look up and then express the "linking
conditions" of a relationship manually in a Manager call.  A task like "get
all the prices for this product" is made easy by the default get_set_on_save
relationship method: @p = $p->prices.  But an only slightly modified task
like "get all the prices for this product that are more than $5" becomes a
(relatively) giant Manager call with hard-coded linking conditions in the
query:

@high_prices = 
  Price::Manager->get_prices(query   =>
 [
   product_id => $p->id,
   price => { gt => 5 },
 ],
 sort_by => 'price);

That's a big step down in easy of use and maintainability for what is only a
slight modification of a formerly simple task.  And if the "prices"
relationship changes, linking back to product in a new way or with new
conditions, then you have to go through the code and find these hard-coded
Manager queries and change them too.

What's needed is an ability to arbitrarily filter the prices related to a
particular product on an ad hoc basis.  That ability can't be added to the
get_set_on_save method because its incompatible with the way that method
works.  Thus the need for a new, "fetch-only" method type, which I'm calling
"find" for lack of a better name.

@high_prices  = $p->find_prices({ price => { gt => 5 }, });

Although that is equivalent to the Manager call above, it's much shorter and
it's more maintainable in the face of relationship changes.  I think it's
also validly an object method because the implicit link of the results to
the parent object is an essential (and non-overridable) part of the Manager
query that's run behind the scenes.

-John



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread Jonathan Vanasco

On Jan 30, 2007, at 7:48 PM, John Siracusa wrote:

> Given that this method will always be called with arguments, and  
> that those
> arguments can change per-call, how can there be any expectation  
> that the
> results will be saved internally?  How would such a feature even work?

it wouldn't -- i can't imagine any circumstance in which it could.

> The whole point of the find method is to allow ad hoc queries.   
> Think of it
> as a Manager call with the query parameters that link one object to  
> another
> being implied, rather than explicitly visible in the args.

i'm in 100% agreement.  but the manager class is that  'special'  
place where all sorts of conditional stuff happens.

it just seems counter-intuitive to everything else in the base rose  
class to me.

> If someone wants to keep the results of a find method call around  
> for a
> while, they certainly have the means to do so by...keeping the results
> around for a while! :)
>
> # Keep @prices around until it's no longer needed
> @prices = $p->find_prices(...);
>
> If there exists a well-defined set of related objects that you want  
> to be
> able to keep inside the parent object, just create a relationship  
> with all
> the parameters that define this set, then use the usual  
> get_set_on_save
> method.

i have no qualms with that.

i just think that the nature of this new function requires that the  
user be made painfully aware of this departure from the standard  
workings.

the consensus is clearly otherwise, but let me expand my suggestions to:

  a- the name semantically notes that it doesn't alter the object  
like other rose functions
  b- the function require a flag that the user know whats going on
  c- this be placed not in rose::db::object, but in some other  
class which extends rose::db::object ( rose::db::objectalt )

i think my issue is that it functions so much like a manager call and  
not like a rose object , yet the point of it is to have the  
functionality of a manager call in the object itself.


-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread John Siracusa
On 1/30/07 9:57 PM, Danial Pearce wrote:
> On 1/31/07, Ask Bjørn Hansen <[EMAIL PROTECTED]> wrote:
>> sub fetch {
>>my $self = shift;
>>my $obj = $self->object_class->new(@_);
>>$obj->load(speculative => 1) ? $obj : undef;
>> }
> 
> Amazing. We also use the exact same method. Well, almost. We golfed
> that shift a bit ;-)
> 
> I wonder if this has a place in Rose itself?

If anyone wants to create and submit a Rose::DB::Object::Manager::Helpers
module filled with such things, feel free! :)

(plus docs and tests, naturally ;)
-John



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread Danial Pearce
On 1/31/07, Ask Bjørn Hansen <[EMAIL PROTECTED]> wrote:
> sub fetch {
>my $self = shift;
>my $obj = $self->object_class->new(@_);
>$obj->load(speculative => 1) ? $obj : undef;
> }

Amazing. We also use the exact same method. Well, almost. We golfed
that shift a bit ;-)

I wonder if this has a place in Rose itself?

-- 
"When I was a kid I used to pray every night for a new bike. Then I
realised that the Lord doesn't work that way so I stole one and asked
him to forgive me."

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread Ask Bjørn Hansen

On Jan 30, 2007, at 12:55, John Siracusa wrote:

I like it!

We have all sorts of utility methods in our model classes to fetch  
child objects where just calling ->children wasn't exact enough.

On a vaguely related note, in our manager class we have the following  
three methods.  In particular the first one is incredibly helpful  
(although I sometimes get tripped up by forgetting by how ->new->load  
needs unique keys).

sub fetch {
   my $self = shift;
   my $obj = $self->object_class->new(@_);
   $obj->load(speculative => 1) ? $obj : undef;
}

sub fetch_or_create {
   my $self = shift;
   my $obj = $self->object_class->new(@_);
   $obj->load(speculative => 1);
   $obj;
}

sub create {
   shift->object_class->new(@_);
}



> # Same as above (hashref as first arg is taken as query)
> @low_prices = $p->find_prices({ price => { lt => 10 } });

This should make it easily call-able from Template Toolkit, too (for  
better or worse).


  - ask

-- 
http://develooper.com/ - http://askask.com/



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread John Siracusa
On 1/30/07 7:59 PM, Danial Pearce wrote:
> What happens when you call ->find_prices with no args?

It's essentially the same as calling a get_set_* method: all the related
objects (as determined by the relationship metadata) are returned.  But if
that's really what you want, you'd just call $p->prices() instead.

-John



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread Danial Pearce
> So, does this method type seem useful?  If so, what do you think of
> the method type name ("find") and the default method name format
> ("find_")?

Ruby uses find. If it's good enough for ruby, it's good enough for me :-)

I agree that it seems obvious the results won't be cached.

What happens when you call ->find_prices with no args?

regards,
Danial
-- 
"When I was a kid I used to pray every night for a new bike. Then I
realised that the Lord doesn't work that way so I stole one and asked
him to forgive me."

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread John Siracusa
On 1/30/07 7:16 PM, Jonathan Vanasco wrote:
>> Every call to find_prices() goes back to the database to get new rows.
>>  Those rows are returned, not saved in the parent object ($p) at all.
> 
> what about temp_find , return_only_find ,  or something else in the
> name to reflect that the results aren't saved ?
> 
> or maybe just require an argument like 'return_only => 1' or
> something similar,
> 
> my main concern is for people who are looking at other's code , or
> haven't touched rose in a while , will know that nothing is saved by
> this operation.

Given that this method will always be called with arguments, and that those
arguments can change per-call, how can there be any expectation that the
results will be saved internally?  How would such a feature even work?

The whole point of the find method is to allow ad hoc queries.  Think of it
as a Manager call with the query parameters that link one object to another
being implied, rather than explicitly visible in the args.

If someone wants to keep the results of a find method call around for a
while, they certainly have the means to do so by...keeping the results
around for a while! :)

# Keep @prices around until it's no longer needed
@prices = $p->find_prices(...);

If there exists a well-defined set of related objects that you want to be
able to keep inside the parent object, just create a relationship with all
the parameters that define this set, then use the usual get_set_on_save
method.

-John



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread Jonathan Vanasco

On Jan 30, 2007, at 3:55 PM, John Siracusa wrote:

> So, does this method type seem useful?  If so, what do you think of
> the method type name ("find") and the default method name format
> ("find_")?  Finally, should this method type be
> created by default for all one-to-many relationships, or should it
> have to be manually requested in the relationship setup?

nice work

but i'm a little uneasy with find , simply because:

> Every call to find_prices() goes back to the database to get new rows.
>  Those rows are returned, not saved in the parent object ($p) at all.

what about temp_find , return_only_find ,  or something else in the  
name to reflect that the results aren't saved ?

or maybe just require an argument like 'return_only => 1' or  
something similar,

my main concern is for people who are looking at other's code , or  
haven't touched rose in a while , will know that nothing is saved by  
this operation.


// Jonathan Vanasco

| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
- - - - - - - - - - - - - - - - - - -
| SyndiClick.com
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
- - - - - - - - - - - - - - - - - - -
|  FindMeOn.com - The cure for Multiple Web Personality Disorder
|  Web Identity Management and 3D Social Networking
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
- - - - - - - - - - - - - - - - - - -
|  RoadSound.com - Tools For Bands, Stuff For Fans
|  Collaborative Online Management And Syndication Tools
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
- - - - - - - - - - - - - - - - - - -



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread John Siracusa
On 1/30/07 6:18 PM, Cees Hek wrote:
>> Finally, should this method type be created by default for all one-to-many
>> relationships, or should it have to be manually requested in the relationship
>> setup?
> 
> For me it is useful enough that it is worth including by default.  But
> as long as it is configurable in the convention manager or base class
> it's OK either way

This sort of thing would be configured in the Metadata class, not the CM,
since it affects the number and type of methods created for each
relationship in a class, not what those method, relationships, and classes
are named, or how they're derived from the database tables.

-John



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread Cees Hek
On 1/31/07, John Siracusa <[EMAIL PROTECTED]> wrote:
> So, does this method type seem useful?  If so, what do you think of
> the method type name ("find") and the default method name format
> ("find_")?

Yes, this is very useful.  I do this type of query all the time, and
it is one of the very few things that I missed from my Class::DBI
days.  As for the name, 'find' is clear and concise, so it works for
me.

>  Finally, should this method type be
> created by default for all one-to-many relationships, or should it
> have to be manually requested in the relationship setup?

For me it is useful enough that it is worth including by default.  But
as long as it is configurable in the convention manager or base class
it's OK either way (I actually haven't had to use the convention
manager yet, since the default conventions used in RDBO match up
closely with the way I like to do things).

Cheers,

Cees

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] Integration with Rose::HTML::Form

2007-01-30 Thread John Siracusa
On 1/30/07, Derek Watson <[EMAIL PROTECTED]> wrote:
> I am using RDBO in conjunction with Rose::HTML::Form for the first time, and
> wonder if there are any guides or examples out there showing some
> conventional integration techniques.  Specifically, how best to use RHF's
> objects returned by object_from_form() style methods to update database
> rows.  Currently I have something like this:
>
>   $form->init_with_customer($session->customer);  # is a
> load()ed RDBO object
>   if ($ENV{REQUEST_METHOD} eq 'POST') {
>
> $form->params(\%ARGS);
> $form->init_fields();
>
> if ($form->validate) {
>   my $c = $form->customer_from_form;  # is RDBO::Customer->new()
>   $c->id($session->customer_id);  # avoid an insert
>   $c->save(update => 1, changes_only => 1, cascade => 1); # force an
> update
> }
>   }
>
> Which works, but seems like there is probably a more conventional way to do
> this.

Well, the details depend on your particular app and on the web
application framework that you're using (if any).  What you have there
looks sensible to me.  One thing I would suggest is that you consider
having the customer_from_form() method do all the stuff required to
set up the object (e.g., setting the id).

In the example above, it's a little tricky because the value for the
id is in $session, which the form knows nothing about.  But in most
web app frameworks, there's usually some way to get at "globally
applicable" data like the session, in which case it's reasonable for
customer_from_form() to return you an object that's completely ready
to be save()d, without any fiddling, and, ideally, without need for an
explicit update => ... argument.

To this end, consider having customer_from_form() internally
load(speculative => 1) the RDBO-derived object based on the id first,
and then pass that object to object_from_form().  This will let you
have forms that contain only a subset of the object attributes, and it
will also ensure that a save() call does the right thing (an update,
in this case).

> But my real problem comes when my form returns other objects as well,
> which are related to customer ($c) . . .for example
>
> if ($form->validate) {
>   my $c = $form->customer_from_form;  # is RDBO::Customer->new()
>$c->id($session->customer_id);  # avoid an insert
>
>   my $a = $form->address_from_form;  # is RDBO::Address->new()
>$c->billing_address($a);
>
>   # inserts a new RDBO::Address record, but unfortunately I want an
>   # update
>   $c->save(update => 1, changes_only => 1, cascade => 1);
>  }
>
> Is there a better way to use these two packages together?

I have db_object_from_form() and init_with_db_object() methods that
will handle a tree of RDBO-derived objects that correspond to a tree
of nested RHTMLO forms.  The code is included at the end of this
email, but it's still "in progress" and may be buggy.  Take from it
what you will.

The basic idea is that, if a Person has a related Address, then the
PersonAddress form is a PersonForm with a nested AddressForm using the
same name as the relationship between Person and Address.  Example:

package Person;
...
__PACKAGE__->meta->setup
(
  ...
  relationships =>
  [
address =>
{
  type  => 'one to one',
  class => 'Address',
  column_map => { id => 'person_id' },
},
  ]
);
...


package PersonForm;

use base 'Rose::HTML::Form';
...
sub build_form
{
  my($self) = shift;

  $self->add_fields
  (
name => { ... },
age  => { ... },
...
  );
}
...


package PersonAddressForm;

use base 'PersonForm';
...
sub build_form
{
  my($self) = shift;

  $self->SUPER::build_form(@_); # Adds Person fields

  # Add a sub-form for Address under the same name as the one-to-one
  # RDBO relationship between Person and Address: "address"
  $self->add_form(address => AddressForm->new);
}

sub person_from_form
{
  my($self) = shift;

  my $person = Person->new;

  if(my $id = $self->field('id')->internal_value)
  {
$person->id($id);
$person->load(with => 'address');
  }

  # Returns a Person object complete with an Address sub-object
  return $self->db_object_from_form($person);
}

sub init_with_person
{
  my($self, $person) = @_;
  $self->init_with_db_object($person);
}

Then, in action:

$form = PersonAddressForm->new;

...init form with params, validate, etc

# The $person object returned has an address sub-object
$person = $form->person_from_form;

# Save the Person and its Address in a single transaction
$person->save;

The code for db_object_from_form() and init_with_db_object() is below.
 Remember, it may be buggy and/or unsuitable for your purposes.  It's
just something I've been playing with.  If/when I'm happy wit

[RDBO] Integration with Rose::HTML::Form

2007-01-30 Thread Derek Watson

Hello,

I am using RDBO in conjunction with Rose::HTML::Form for the first time, and
wonder if there are any guides or examples out there showing some
conventional integration techniques.  Specifically, how best to use RHF's
objects returned by object_from_form() style methods to update database
rows.  Currently I have something like this:

 $form->init_with_customer($session->customer);  # is a load()ed RDBO
object
 if ($ENV{REQUEST_METHOD} eq 'POST') {

   $form->params(\%ARGS);
   $form->init_fields();

   if ($form->validate) {
 my $c = $form->customer_from_form;  # is RDBO::Customer->new()
 $c->id($session->customer_id);  # avoid an insert
 $c->save(update => 1, changes_only => 1, cascade => 1); # force an
update
   }
 }

Which works, but seems like there is probably a more conventional way to do
this.  But my real problem comes when my form returns other objects as well,
which are related to customer ($c) . . .for example


   if ($form->validate) {

 my $c = $form->customer_from_form;  # is RDBO::Customer->new()
 $c->id($session->customer_id);  # avoid an insert

 my $a = $form->address_from_form;  # is RDBO::Address->new()
 $c->billing_address($a);

 # inserts a new RDBO::Address record, but unfortunately I want an
update
 $c->save(update => 1, changes_only => 1, cascade => 1);

   }


Is there a better way to use these two packages together?


Thanks in advance,
DW
-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


[RDBO] New "find" method type for one-to-many relationships

2007-01-30 Thread John Siracusa
In SVN, I've just added a new method type to one-to-many relationships
(no docs yet).  Right now, I'm calling it "find".  It's for fetching
related objects using ad-hoc queries instead of being constrained to
the mapping defined in the relationship metadata itself.  It has no
ability to "set" related objects; it just returns them.  Here's an
example using the Product/Price classes from the tutorial.

$p = Product->new(id => 123)->load;

## Example use of the default "get_set_on_save" method
## for the "prices" one-to-many relationship

@prices = $p->prices; # get

... # modify @prices in some way

$p->prices(@prices); # set...
$p->save; # ...on save (db modified here)

## Example use of the new "find" method for the "prices"
## one-to-many relationship

@high_prices = $p->find_prices(query   => [ price => { gt => 99 } ],
   sort_by => 'region',
   ...any other manager args here...);

@low_prices = $p->find_prices(query => [ price => { lt => 10 } ]);

# Same as above (arrayref as first arg is taken as query)
@low_prices = $p->find_prices([ price => { lt => 10 } ]);

# Same as above (hashref as first arg is taken as query)
@low_prices = $p->find_prices({ price => { lt => 10 } });

Every call to find_prices() goes back to the database to get new rows.
 Those rows are returned, not saved in the parent object ($p) at all.

During each query, the mapping constraints defined in the relationship
metadata that connect the parent object to its related objects are
implicit, though they may be modified by conflicting, explicit
arguments in the call.

So, does this method type seem useful?  If so, what do you think of
the method type name ("find") and the default method name format
("find_")?  Finally, should this method type be
created by default for all one-to-many relationships, or should it
have to be manually requested in the relationship setup?

-John

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object