Entry tags:
Models
I was idly musing on my journal that DW is approaching the MVC model of web development, as it's got Controllers, in the form of functions that get called to handle pages, and Views in the form of the Template Toolkit (or even BML). It even has Routing (which doesn't get a letter in MVC ;) ) to bind the right url to the right Controller. What DW doesn't have is the M part, the Model, which is normally a class that handles access to a table in a database, and I was musing about this because some of the functionality would have been a bit useful for the work I was doing then, even if I do enjoy the fact that not fitting into the MVC concept means DW is a bit more freeform. Anyway, I was wondering if there was any reason that DW didn't have a Model class.
denise suggested that I ask, as often something doesn't exist because nobody's done it yet.
Do you think that a general database interface class, like a Model would be useful to DW? Do you think DW should go that way, or are people genuinely happy just hard-coding their SQL queries in various objects, as is done now? Admittedly, the DBI layer does a lot of what Models do, such as quote escaping and input sanitisation, although it doesn't quite do the same job, and it won't error check your SQL query input to check whether you are using the right fields and values, or automatically make your SQL queries for you if you provide it with sensible data and want to do a common operation. If something like a Model is useful, how far should one go with them? Do you find things like behaviours and relationships useful, or do they just get in your way?
Further, if I wrote a simple Model class, would anyone other than me use it? Would anyone know how? Would anyone even care? ;)
#The model fetches all the columns from the database and figures out all the primary keys and datatypes
my $userkeywordstable = Model->new("userkeywords");
#Gets the whole table
my $results = $userkeywordstable->find("all");
#Returns just the keywords column belonging to userid 1
my keywords = $userkeywordstable->find( "all", "keywords", { "userid" => 1 } );
#Return the primary key columns for this table
my $pkeys = $userkeywords->primary_keys;
#Prepare some new tags for a user and add them
#If the userkeywords table was autoincrement, I wouldn't need to work out the keys as the model would do it for me.
for( my $i=0; $i<@newtags; ++$i )
{
push $data, \{ userid=>$user->{userid}, "kwid"=>$maxkw+$i, "keyword"=>$newtags[$i]};
}
$userkeywordstable->insert($data);
if( $userkeywordstable->err )
{
print $userkeywordstable->errmsg;
}
#Update keyword 0, userid 34 with keyword anime
$userkeywordstable->update( { kwid => 0, userid => 34 }, {"keyword"=>"anime"} );
#Produces error, parentkwid isn't in this table!
$userkeywordstable->update( {kwid=>0, userid => 34}, {"parentkwid"=>9} );
#Produces error, didn't you know keyword isn't a number, numbskull!
$userkeywordstable->update( { kwid => 0, userid => 34 }, {"keyword"=>9} );
#I have some data I have worked on that needs updating, figure it out by yourself which fields are the primary keys and update as necessary
my $data = $userkeywordstable->find("all");
... #Work done here
$userkeywordstable->update($data);
#Activate advanced behaviours for this table
$userkeywordstable->behavesAs("user", "threaded");
#Find all tags belonging to user name aphenine and return them in threaded mode
#The user behaviour automatically pulls the userid for a name, which is why userid is no longer in the WHERE clause (third argument), but user is in the options (fourth).
$userkeywordstable->find( "threaded", undef, undef, {"user" => "aphenine"} );
#Get the tag containing the word anime, and all entries which have those tags in them (using relationships).
$userkeywordstable->manyToMany("logtags2", "logkeywords"); #relates to posts (in logtags) via logkeywords table
$userkeywordstable->find("all", undef, {"keyword"=>"anime"}, {"user" => "aphenine", "recurse"=>1}); #return the tag and the entries it appears in
![[staff profile]](https://www.dreamwidth.org/img/silk/identity/user_staff.png)
Do you think that a general database interface class, like a Model would be useful to DW? Do you think DW should go that way, or are people genuinely happy just hard-coding their SQL queries in various objects, as is done now? Admittedly, the DBI layer does a lot of what Models do, such as quote escaping and input sanitisation, although it doesn't quite do the same job, and it won't error check your SQL query input to check whether you are using the right fields and values, or automatically make your SQL queries for you if you provide it with sensible data and want to do a common operation. If something like a Model is useful, how far should one go with them? Do you find things like behaviours and relationships useful, or do they just get in your way?
Further, if I wrote a simple Model class, would anyone other than me use it? Would anyone know how? Would anyone even care? ;)
#The model fetches all the columns from the database and figures out all the primary keys and datatypes
my $userkeywordstable = Model->new("userkeywords");
#Gets the whole table
my $results = $userkeywordstable->find("all");
#Returns just the keywords column belonging to userid 1
my keywords = $userkeywordstable->find( "all", "keywords", { "userid" => 1 } );
#Return the primary key columns for this table
my $pkeys = $userkeywords->primary_keys;
#Prepare some new tags for a user and add them
#If the userkeywords table was autoincrement, I wouldn't need to work out the keys as the model would do it for me.
for( my $i=0; $i<@newtags; ++$i )
{
push $data, \{ userid=>$user->{userid}, "kwid"=>$maxkw+$i, "keyword"=>$newtags[$i]};
}
$userkeywordstable->insert($data);
if( $userkeywordstable->err )
{
print $userkeywordstable->errmsg;
}
#Update keyword 0, userid 34 with keyword anime
$userkeywordstable->update( { kwid => 0, userid => 34 }, {"keyword"=>"anime"} );
#Produces error, parentkwid isn't in this table!
$userkeywordstable->update( {kwid=>0, userid => 34}, {"parentkwid"=>9} );
#Produces error, didn't you know keyword isn't a number, numbskull!
$userkeywordstable->update( { kwid => 0, userid => 34 }, {"keyword"=>9} );
#I have some data I have worked on that needs updating, figure it out by yourself which fields are the primary keys and update as necessary
my $data = $userkeywordstable->find("all");
... #Work done here
$userkeywordstable->update($data);
#Activate advanced behaviours for this table
$userkeywordstable->behavesAs("user", "threaded");
#Find all tags belonging to user name aphenine and return them in threaded mode
#The user behaviour automatically pulls the userid for a name, which is why userid is no longer in the WHERE clause (third argument), but user is in the options (fourth).
$userkeywordstable->find( "threaded", undef, undef, {"user" => "aphenine"} );
#Get the tag containing the word anime, and all entries which have those tags in them (using relationships).
$userkeywordstable->manyToMany("logtags2", "logkeywords"); #relates to posts (in logtags) via logkeywords table
$userkeywordstable->find("all", undef, {"keyword"=>"anime"}, {"user" => "aphenine", "recurse"=>1}); #return the tag and the entries it appears in
no subject
push $data, \{ userid=>$user->{userid}, "kwid"=>$maxkw+$i, "keyword"=>$newtags[$i]};
Er, really? A reference to a reference to an anonymous hash? What does the extra \ get you?
Also, doesn't it have to be
push @$data, ...
orpush @data, ...
?no subject