From: InetDavid on 19 Apr 2010 13:38 Apologies for the complicated setup, but there *is* actually method behind my madness here! I'm currently working to implement the Active Record pattern for TclOO, modeled after the Ruby on Rails (RoR) implementation. (http:// api.rubyonrails.org/files/vendor/rails/activerecord/README.html). So far, by using classmethod and classvar from TclOO Tricks (http:// wiki.tcl.tk/21595) I've been able to get a proof of concept ActiveRecord::Base class working with only a small derived class for each model, just like RoR. This allows me to retrieve records from a MySQL database with just one statement and have the resulting row(s) returned as a list of TclOO model instances with access methods for each table column: % set result [Model find last] ::oo::Obj5 % $result id 703 % $result name Some Name % $result name "New Name" New Name % $result save 1 % My current problem is that I'm now trying to implement the ActiveRecord::Base "new" and "create" methods which will return a new (unsaved) row object or will create a new row in the database and return that row. I want my own "new" and "create" class methods, but I also need to be able to use the original "new" method to build new model instances. I can easily create a new "new" method, but how can I call the previous "new" method to get an instance of the derived, Model class? oo::class create ActiveRecord::Base { classmethod new args { set model_class [lindex [self caller] 0] ;# kludge to get model class name from class method set model_instance [????] ;# How can I get a new Model instance here??? [...] } } oo::class create Model { superclass ActiveRecord::Base classmethod unknown args { ::ActiveRecord::Base {*}$args } ;# since classmethods aren't inherited yet } I've tried using "oo::objdefine Model rename create old_create" but got the error "method create does not exist", probably because it's defined in oo::class. I was able to create a forward to the original with "oo::objdefine Model forward old_create oo::class::create", but when I try to use it with "Model old_create" I get "empty command name """. Does anyone have a way for me to make my own create/new methods and still be able to find the old methods from within my class? David Schmidt
From: tom.rmadilo on 19 Apr 2010 15:43 On Apr 19, 10:38 am, InetDavid <dav...(a)tower-mt.com> wrote: > Apologies for the complicated setup, but there *is* actually method > behind my madness here! > > I'm currently working to implement the Active Record pattern for > TclOO, modeled after the Ruby on Rails (RoR) implementation. (http:// > api.rubyonrails.org/files/vendor/rails/activerecord/README.html). So > far, by using classmethod and classvar from TclOO Tricks (http:// > wiki.tcl.tk/21595) I've been able to get a proof of concept > ActiveRecord::Base class working with only a small derived class for > each model, just like RoR. This allows me to retrieve records from a > MySQL database with just one statement and have the resulting row(s) > returned as a list of TclOO model instances with access methods for > each table column: > > % set result [Model find last] > ::oo::Obj5 > % $result id > 703 > % $result name > Some Name > % $result name "New Name" > New Name > % $result save > 1 > % > > My current problem is that I'm now trying to implement the > ActiveRecord::Base "new" and "create" methods which will return a new > (unsaved) row object or will create a new row in the database and > return that row. > > I want my own "new" and "create" class methods, but I also need to be > able to use the original "new" method to build new model instances. I > can easily create a new "new" method, but how can I call the previous > "new" method to get an instance of the derived, Model class? > > oo::class create ActiveRecord::Base { > classmethod new args { > set model_class [lindex [self caller] 0] ;# kludge to get model > class name from class method > set model_instance [????] ;# How can I get a new Model > instance here??? > [...] > } > > } > > oo::class create Model { > superclass ActiveRecord::Base > classmethod unknown args { ::ActiveRecord::Base {*}$args } ;# since > classmethods aren't inherited yet > > } > > I've tried using "oo::objdefine Model rename create old_create" but > got the error "method create does not exist", probably because it's > defined in oo::class. I was able to create a forward to the original > with "oo::objdefine Model forward old_create oo::class::create", but > when I try to use it with "Model old_create" I get "empty command name > """. > > Does anyone have a way for me to make my own create/new methods and > still be able to find the old methods from within my class? There must be a good reason why most sophisticated organizations store their data in relational databases. My guess is that the data model is much more powerful than the OO model. Trying to equate the two is a hopeless pursuit. If anyone wants a good relational to OO model, try JDBC. For Tcl, AOLserver has ns_db, which represents row data as an ns_set. The key differences with OO is that correct relational models allow multiple columns with the same name and columns are ordered (of course the result rows are also structurally ordered). JDBC follows this model, most other OO systems do not. One key concept of OO is modeling. Model the data in a relational database, don't take shortcuts. One option is to offer multiple accessor APIs: one API covers the usual case when columns are referenced by name, the second accesses columns by their order in the query result. Only the second is guaranteed to return valid results, only the second represents the query result.
From: InetDavid on 19 Apr 2010 16:13 On Apr 19, 12:43 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > On Apr 19, 10:38 am, InetDavid <dav...(a)tower-mt.com> wrote: > > > > > Apologies for the complicated setup, but there *is* actually method > > behind my madness here! > > > I'm currently working to implement the Active Record pattern for > > TclOO, modeled after the Ruby on Rails (RoR) implementation. (http:// > > api.rubyonrails.org/files/vendor/rails/activerecord/README.html). > > [...] > There must be a good reason why most sophisticated organizations store > their data in relational databases. My guess is that the data model is > much more powerful than the OO model. Trying to equate the two is a > hopeless pursuit. If anyone wants a good relational to OO model, try > JDBC. For Tcl, AOLserver has ns_db, which represents row data as an > ns_set. The key differences with OO is that correct relational models > allow multiple columns with the same name and columns are ordered (of > course the result rows are also structurally ordered). JDBC follows > this model, most other OO systems do not. > > One key concept of OO is modeling. Model the data in a relational > database, don't take shortcuts. One option is to offer multiple > accessor APIs: one API covers the usual case when columns are > referenced by name, the second accesses columns by their order in the > query result. Only the second is guaranteed to return valid results, > only the second represents the query result. Regardless of whether you think the ActiveRecord model is valid (it *does* address the issues you raise and I invite you to read the web page above thoroughly), I would still like to know if it's possible to create my own "new" method and still be able to call the oo::object::new method. In particular, "new" is difficult because it uses the name of the class used to determine which object to instantiate ("[Model new]" creates a new instance of Model). Can that be accomplished within the TclOO framework or must I choose different method names? David
From: tom.rmadilo on 19 Apr 2010 17:08 On Apr 19, 1:13 pm, InetDavid <dav...(a)tower-mt.com> wrote: > On Apr 19, 12:43 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > > > > > > > On Apr 19, 10:38 am, InetDavid <dav...(a)tower-mt.com> wrote: > > > > Apologies for the complicated setup, but there *is* actually method > > > behind my madness here! > > > > I'm currently working to implement the Active Record pattern for > > > TclOO, modeled after the Ruby on Rails (RoR) implementation. (http:// > > > api.rubyonrails.org/files/vendor/rails/activerecord/README.html). > > > [...] > > There must be a good reason why most sophisticated organizations store > > their data in relational databases. My guess is that the data model is > > much more powerful than the OO model. Trying to equate the two is a > > hopeless pursuit. If anyone wants a good relational to OO model, try > > JDBC. For Tcl, AOLserver has ns_db, which represents row data as an > > ns_set. The key differences with OO is that correct relational models > > allow multiple columns with the same name and columns are ordered (of > > course the result rows are also structurally ordered). JDBC follows > > this model, most other OO systems do not. > > > One key concept of OO is modeling. Model the data in a relational > > database, don't take shortcuts. One option is to offer multiple > > accessor APIs: one API covers the usual case when columns are > > referenced by name, the second accesses columns by their order in the > > query result. Only the second is guaranteed to return valid results, > > only the second represents the query result. > > Regardless of whether you think the ActiveRecord model is valid (it > *does* address the issues you raise and I invite you to read the web > page above thoroughly), I would still like to know if it's possible to > create my own "new" method and still be able to call the > oo::object::new method. In particular, "new" is difficult because it > uses the name of the class used to determine which object to > instantiate ("[Model new]" creates a new instance of Model). Can that > be accomplished within the TclOO framework or must I choose different > method names? Right, so just explain how to handle a row that has two columns with the same name, and how do you enforce column order? This is a simple thing, but very important. If you can't do these two things, you haven't successfully represented/mapped a relation in/to OO. The link you provided does not address either of these two issues. I assume that means failure. If you disagree, please provide an example, not an API reference.
From: tom.rmadilo on 22 Apr 2010 16:06 On Apr 20, 2:26 am, "Donal K. Fellows" <donal.k.fell...(a)manchester.ac.uk> wrote: > On 19 Apr, 20:43, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > > > There must be a good reason why most sophisticated organizations store > > their data in relational databases. My guess is that the data model is > > much more powerful than the OO model. > > I'd guess that you're a bit off-base there. Often, I'd expect to see a > more prosaic foundation such as "We store data in the database because > that's what we've always done". I'd argue that the additional power of > a relational database comes in theory from the ability to support non- > trivial ad hoc queries, and in practical terms the real bonus is that > someone else (the DB vendor) has figured out how to perform ACID > updates. (Atomic, Consistent, Isolated, Durable data handling is a > good thing.) Not going to disagree with off-base. But the reason large organizations use relational databases is because of the ability to normalize data and to query the data, producing new objects from the base objects. ACID just deals with creating and maintaining data in a consistent state. Most of the power is in dynamic querying. What really screws up the relational to OO mapping is the dynamic query language and the dynamic result table structure. Base tables insert/ update/delete work very well with object systems. In fact, it is very simple to automate insert/update/delete operations when given the data model. The big problem is select. > > Trying to equate the two is a > > hopeless pursuit. If anyone wants a good relational to OO model, try > > JDBC. > > That's an interface to an SQL database, not a relational-object > mapping. Never claimed it was a mapping. You can map insert/update/delete, but not select. > For mappings in the Java world, look at things like EJB > (especially Entity Beans). Most of the successful ORMs tend to be > class-first though, using the class(es) to create the DB schema as > that allows forcing things like unique column names. The original schema must have unique column names for base tables, but not so for derived tables or queries. Solving the base table interface is not interesting, although it is important. Solving the select query/ result table interface is difficult. > Object-Relational Mapping is not just about doing queries and getting > the results back. It's about conceptually having the same model and > instances in both the database and the object world. Since queries dynamically create new objects, the OO model suffers. Relational "objects" are constructed by the query. > It's arguably the > case that it is impossible in general, but there are significant > subsets of the universe for which it is practical. The universe includes all insert/update/delete queries on base tables, plus most select queries on a single base table. The above isn't quite true. Any time you have to deal with multiple classes of users with different permissions on tables and columns, you run into real trouble with direct relational to object mapping. You need an intermediate mapping. Fortunately such a mapping can double as an user interface definition. This still doesn't help with select queries.
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Dictionary Compare for Alphanumeric Strings in TCL Next: string length & regexp problem |