Hi Jess,

I'm quite willing to give back to the project in terms of editing documentation 
but thought this might be limited to editing, because it should be written from 
the perspective of someone who knows the "right" way to use the system or its 
core philosophy.

I can't reply at length now since it is 1AM but will think about it some more. 
For a quick reply, yes I've read that page, the cookbook page, 
Relationships::Base, page, etc. and a number of times. But to me anyway it 
seems to assume a lot of knowledge, skips describing the foundation of what the 
module is intended to do, and skimps on the important parts. In order to get a 
feeling of which method to pick and how to practically use it you basically 
have to read many different documents over and over, pulling information in 
about other methods, and finally of course already know a lot of about what is 
really going on in the database. To me the module ought to be shielding you 
from having to think about it so much but that probably isn't realistic. To 
illustrate a couple points come to mind:

The very helpful replies I received about "insane layout" (i.e. having an id in 
both tables pointing to each other), it is not obvious to even someone who has 
used databases and perl a lot for small systems it isn't sane. Of course if the 
two relationships get out of sync then you might get different data depending 
on which table you start from, hence the insanity. But very little info on 
designing ORM based systems with lots of objects and relationships.

Also no information about Relationships and foreign relations. In fact I had 
been under the impression at least that mysql3 couldn't do foreign relations, 
and I'd decided to do it all using DBIx Relationships instead. The notion of 
foreign keys in the db being useful for maintaining integrity of data is not 
mentioned; it seems that a Relationship would do something like this but of 
course it isn't the same.

Also check out this part of the FAQ you mention, it is quite confusing actually.
"Relationships
   ... define a foreign key relationship where the key field may contain NULL? 
Just create a belongs_to relationship, as above. If the column is NULL then the 
inflation to the foreign object will not happen"

Now according to Matt's very helpful notes in the ML, allowing NULL in your db 
schema is used to tell belongs_to to be an optional Relationship, meaning that 
it will not enforce the belongs_to rule and autovivify. In other words use NULL 
so DBIx::Class::Relationships does not do inserts when it thinks that would be 
"the right thing". (or you can make a dummy record, but that's painful I found).

But the above passage comes from the other direction, assuming first that the 
developer wants to allow a NULL, and then explains that allowing NULL will 
disable object inflation (which I did not know until I just checked now!). It 
doesn't say that it disables autovivification, even though anything that does 
an INSERT is to me a potentially naughty thing and deserves to be 
well-documented. 

Now we go back to the perldoc for the belongs_to method does not mention that 
object inflation will be disabled, rather saying "If the relationship is 
optional -- i.e. the column containing the foreign key can be NULL -- then the 
belongs_to relationship does the right thing. Thus, in the example above 
$obj->author would return undef. However in this case you would probably want 
to set the join_type attribute so that a LEFT JOIN is done, which makes complex 
resultsets involving join or prefetch operations work correctly. "

This does not explain whether object inflation being "disabled" just means 
returning an undef if it's a NULL (which of course would be intuititive) or 
whether it means something like $listing->coupon will not return an object in 
any case if the field in question allows NULL. It also does not explain about 
from which side to make a Relationship (or both sides - no that's insane 
apparently, despite being logical in English anyway), though it is mentioned in 
the FAQ (regarding one-to-many) that "Currently these need to be set up 
individually on each side."

Also the pod mentions left joins and right joins. As I understand it a normal 
join would only provide records that match across the two tables but a left 
join would also show items not matched in the left table, and similarly right 
would for the right table. But this is not explained, and it is not clear why 
an ORM would not handle this sort of thing for you, or how the left/right sql 
metaphor for tables translates into parent object -> child object metaphor of 
DBIx::Class.

Something about usage of foreign relations in the db for integrity control 
would be helpful, and would explain the difference between what 
DBIx::Class::Relationships offers and what the db offers.

I think it would be quite helpful if a design example similar to what I had 
posted is used (you can use my objects if you want). For one thing there is 
confusion among people who want to use an object oriented system but then have 
to build an sql table schema to fit it. They start thinking in an object 
oriented fashion. Then they have to translate it into tables in their head 
(probably writing sql create statement by hand or with a tool like phpmyadmin, 
though maybe they really should use DbDesigner, or maybe they should just stay 
away from mysql and go to postresql). Anyway once they have the tables they 
start using DBIx::Class and it seems to work nicely, except it fails sometimes, 
and they end up having to figure out the more esoteric parts of the module 
which are not as well documented. I think this tends to lead to spaghetti 
objects, insane layout, and fragile schemas.

Well this turned out to be a long post. Sorry, and no offense meant at all, 
just that I'm willing to contribute to documentation in thanks for your 
support. So this is in response to how a non-dba person might see the module. 
I've used DBI and CDBI, etc. with Perl for many years but don't make my living 
as a database designer, and haven't needed to get high end database performance 
(my high performance mod_perl systems have used a Perl embedded db or a C++ 
based system). 

Anyway to try and wrap up this unending post, I would just mention that the 
DBIx::Class docs spend a lot of time talking about how you can agilely use lots 
of different chained methods to search or insert in related tables and so on, 
but spend very little time talking about what this actually does in the db, 
what the actual db schema is, whether something is available in mysql or 
another db or not, etc. For example I don't think I saw anything about 
sequences. I don't think foreign keys or null values were mentioned in the 
Artist/CD applications. Nothing about what "doing the right thing" could mean 
or how to design an application starting with a Perl (DBIx::Class) design and 
then what kind of tables you should make for those objects. I think this sort 
of thing might be useful.

Also I find a lot of my code tends to be paranoid. I test the results of all db 
updates and capture errors, displaying an error message and halting when 
processing hits an error. So I tend in my Catalyst app to first get required 
input arguments, test them (or die with a pretty error page to browser), then 
look up chained object info, testing whether the next link in the chain 
actually returns me an object or not and dying prettily each time if it 
doesn't. Finally I know I have good data and do the processing and output a 
template.

This is probably way too much code. For one thing a lot of this should be 
covered probably by integrity assurances in the db, at least that is my 
interpretation of a "sane layout". Though probably not to be expected if my 
client is editing the db manually. Also a lot of that should be done in Model 
modules, I'd expect, certainly it isn't DRY since I do it over and over. And 
I'd like to be able to look up a bunch of stuff with DBIx::Class and then check 
to see if any errors occurred, as one might with eval and $@, instead of doing 
so many tests, just to reduce the amount of code but maybe that isn't a great 
idea. So I admit the last app had just about all code in the controller modules 
and just schema and relationship creation lines in the model modules. This is 
not what the Catalyst people seem to like (since it makes it hard to access the 
system from command line or other interface than ordinary html browser) but it 
does seem to be what the cookbooks offer. So great
 volumes of extremely sane, DRY, smart layouts and uses of DBIx::Class and 
especially in a Catalyst environment would be quite useful to the world I 
think. This might require the developers of Catalyst and DBIx::Class to put 
their heads together but to me the more robust the better and if that can be 
done with less code and more extensibility to other interfaces then best yet.

Also for what it's worth, I found both startling, amazing, cool, mysterious and 
scary that I could access chained objects (in dot notation) from within a TT2 
template that are not provided from the calling Perl subroutine, without any 
attributes specified, and that such a call could even cause INSERTS in my db 
from just trying to view what I'd planned as a read-only page in the browser 
(due to auto-vivification). Also if objects aren't available (I suppose if 
NULL, or if the id does not have a corresponding row in the other table) TT2 
will crash I think, so you have to use TT2's defined keywords to try to sneak 
up on them, and sometimes that won't work it seems. So while this is a Catalyst 
and TT2 issue I think you might want to add something about this, and what 
actually is going on (what kind of a search is being made) when you call an 
object in TT2. (I'm talking about the case in which your TT2 template is 
displaying a list of "listing" objects, and if "r" is a single
 listing, you type "r.customer.b_company" to try and get the company name of 
the customer that owns the listing.)

Well I don't provide these as criticism, so much as trying to describe how the 
module looks to someone who does not have the same background as the developer. 
I hope you take it with a grain of salt too since it is more a measure of my 
own usage of it and lack of knowledge than as an imperative that you must do 
something about it!).

Thanks again and if you wish I would be happy to contribute or edit docs. 
Again, also I would like to thank Matthew Trout for his fabulous comments and 
help.

Matt Rosin


       
____________________________________________________________________________________
Moody friends. Drama queens. Your life? Nope! - their life, your story. Play 
Sims Stories at Yahoo! Games.
http://sims.yahoo.com/  

_______________________________________________
List: http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
Wiki: http://dbix-class.shadowcatsystems.co.uk/
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
Searchable Archive: http://www.mail-archive.com/[email protected]/

Reply via email to