On Sep 2, 11:47 am, "Daniel Parker" <[EMAIL PROTECTED]> wrote: > I poked around in DataObjects, and I've seen a version where it injects > another method or two when you're using sql-specific repositories. Not hard > to do it that way. Of course nobody would want to compose raw SQL when > they're not using a sql engine.
Daniel, I think you mean DataMapper. Anyways. Yeah, so what's your use-case for this? No offense, just going to lay out my reasoning for why DM is the way it is. First, lemme clarify something: The order of the properties is not the order that an object should be materialized in. That depends on Query#fields. If you try to materialize just by "lining up the fields" you'll quickly run into issues with composite fields or lazy-loaded attributes and eventually prefetching. I ask because AR::find_by_sql is wrong. It's a bleeding of responsibilities. DM is for CRUD. It's an O/R Mapper, not a reporting tool. The objects returned from a find_by_sql are often not persistable objects and it completely subverts the majority of the code in DM. As Adam suggested, if all you want is a convenience to translate query results into object instances a simple helper in your application could manage that with very little work. Execute a DO query, map the results to objects. Something like: : # This is probably close, but untested, caveat emptor. : module ApplicationHelper : def query(model, sql, *args) : connection = DataObjects::Connection.new(Merb.config[:databases] [:default]) : reader = connection.create_command(sql).execute_reader(*args) : results = [] : while(reader.next!) do : results << model.new(Hash[*reader.fields.zip(reader.values).flatten]) : end : return results : ensure : connection.close : end : end You could even pass the fields explicitly to ensure everything's type- cast properly with Command#set_types. Reporting tools are valuable for sure. But when you don't have one handy, the solution is not a half-baked extension to your O/RM. Just use the database-drivers directly. It only adds a line or two of code to use the DO connections directly, and the performance pay-off is well worth it. So. Why do the objects that come back need to be model instances? I'll share an example of how we've done it wrong on an app or two... We have a Photo model with a #preview(max_width, max_height) method. It's awesome. It takes a look at itself to determine wether it's published or not, and if so, generates a preview image or thumbnail at the appropriate size (retaining aspect-ratio) in the public folder so Apache can serve it. If it's unpublished, it generates a file in a private folder and returns the path so the app can X-SENDFILE it. So it depends on knowing the source-path of the original image, and wether it's published. Problem is, when we want to do a custom, fast query on our /photos/ index page to bring back the photos for a specific user, we get these raw Arrays, not Photos. Ok, easy enough, we move it to a class-method that takes the id, created_at, and published_at so we know where on the file-system to find the source file, whether to watermark it, etc. The problem is, we're making it the responsibility of the Photo model to know how to generate preview images, and that just doesn't make sense. What we need here is a separate class that lives outside of our domain- model. A Preview class that can take these attributes. It's easier to test. It's cleaner with a clear separation of responsibilities. It's easier to re-use between projects as long as our Photo implements a fairly simple interface. Most importantly, it just works with a few pieces of data, and it doesn't matter where it comes from. It's cake to use it with models, Arrays, Structs, whatever. And it lives in the right Layer of our application. Not the Business Logic Layer. It lives much higher in the stack, in the Application Layer. And so... it's a problem you can work around, and I'd wager that in many if not most cases, your application code will be the better for it. So, with that said, it's difficult for me to anticipate a "I can't write this page I need because DM doesn't have this feature" sort of use-case, but if you can come up with one I'll do my best to give it some genuine consideration. Thanks, -Sam --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "DataMapper" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/datamapper?hl=en -~----------~----~----~----~------~----~------~--~---
