Looking for ORM for 'legacy' database.

D

Dave Howell

I feel I should start with some pre-emptive apologies. I used to =
subscribe to this list, but haven't been reading it for a year or so, so =
I may have missed the answer to my question. (I did try finding it in =
the list archives, of course.) Also, I'm a little frustrated, and that =
might adversely influence the tone of this message. I'll try to avoid =
that, but I beg your forgiveness if I sound a little snide.=20

I started using Ruby years ago, but, although I built my first =
database-driven website in 1998, before Microsoft had invented ASP =
pages, I'd never had the time to work with Rails. I've been looking =
forward to it, and last week finally had the chance to take a closer =
look. To my dismay, I discovered that one of the core opinions of this =
'opinionated software' is exactly opposed to one of mine. For my work, =
the data is the supreme treasure, and the database engine is the =
god-emperor.=20

"Migrations" really had me mystified when I started trying to figure out =
Rails. The idea that I would ever consider letting the middleware have =
any kind of write access to the database schema seemed so improbable =
that I spent rather a lot of time looking for the 'other' tutorial, the =
one where you start with the data and work your way forward to the web =
site, rather than starting in the middle and working out in both =
directions.=20

I eventually figured out that Rails just doesn't work that way. Clearly, =
the paradigm that it uses is very effective for a lot of people. That's =
a fine thing; I'm not here to try to convince people that it's doing =
stuff the 'wrong way.' I just need to find something that supports a =
more data-centric (and database-centric) approach.=20

I have an old site I'd like to modernize, and a brand-new site to =
develop. My pre-existing site is currently using WiTango as the =
middleware, and I'd love to keep using it, but can't afford the $5,000 =
non-restricted server license. I've been looking at various non-Rails =
options, and it looks like, to a certain degree, it turns into a =
snap-your-own-together situation, where I get to pick a framework (like =
Merb, Padrino, Ramaze, Nitro, etc.), an adapter (Mongrel, Rack, WEBrick, =
Thin, etc.), a templating engine (Erubis, Liquid, Haml, Markaby, Radius, =
etc, etc, etc, etc), and an ORM. Since I'm working from the database =
out, I'm starting with the ORM, and will then find parts that work well =
with it.

Not too surprisingly, most explanations and introductions tend to =
compare the new ORM to what somebody would have been doing in Rails; =
most people reading those pages will have already worked in Rails. It =
took me a little while to figure out that most of the information *I* =
wanted was appearing under the phrase 'legacy database.' I'm not dealing =
with a 'legacy' database for the new project; I'm still finishing up the =
work on the PostgreSQL schema. It's brand new, and I'm leveraging =
Postgres's feature set hard in order to protect the integrity of the =
data. Composite unique keys, foreign keys, and two different custom =
datatypes are part of the schema, for example.

ActiveRecord did turn out to have a command available to build its =
migration file (I think that's what it was) FROM the schema, rather than =
vice versa. Unfortunately, it only managed to extract about 20% of the =
tables, because I'm using UUIDs for the primary keys, not sequences or =
integers, and it didn't know what to do with a UUID. I have no doubt =
that there is some place, somewhere, where I could define a new database =
type, but a couple of hours digging and fiddling with various files =
didn't lead me to the solution.=20

I did get the distinct impression that, while it was almost certainly =
possible, it probably wouldn't ever be smooth. I decided it made more =
sense to try to find an ORM that was more comfortable with the idea it =
could only reflect the database's schema, rather than trying to make the =
DB schema conform to Ruby objects.=20

So far, I've found DataMapper, Friendly, M4DBI, Ohm, and Sequel as =
possible alternative ORMs, but all the documentation for them is heavy =
with terminology and jargon from Rails, and usually brags about how I =
can make tables appear in my database magically from my Ruby objects. =
Which ORMs are better for connecting to my Postgres databases in a way =
that will best take advantage of, or at least not get in fights with, =
the constraints enforced by Postgres itself?

Thanks for reading to the end of a pretty long message, and thanks even =
more to those of you who help me figure out where to look for the =
answers. :)
 
E

Edward Middleton

D

Dave Howell

Thanks for reading to the end of a pretty long message, and thanks
even more to those of you who help me figure out where to look for = the
answers. :)
=20
Get a copy of "Patterns of Enterprise Application Architecture"[1] = read
and grok that first. If you are just confirming your model to your
database you don't need objects. They will just be a distraction ;)

Well, I'm going to need *something* to hand over to the templating =
engine in order to build web pages.=20
 
J

Jack Christensen

I feel I should start with some pre-emptive apologies. I used to subscribe to this list, but haven't been reading it for a year or so, so I may have missed the answer to my question. (I did try finding it in the list archives, of course.) Also, I'm a little frustrated, and that might adversely influence the tone of this message. I'll try to avoid that, but I beg your forgiveness if I sound a little snide.

I started using Ruby years ago, but, although I built my first database-driven website in 1998, before Microsoft had invented ASP pages, I'd never had the time to work with Rails. I've been looking forward to it, and last week finally had the chance to take a closer look. To my dismay, I discovered that one of the core opinions of this 'opinionated software' is exactly opposed to one of mine. For my work, the data is the supreme treasure, and the database engine is the god-emperor.

"Migrations" really had me mystified when I started trying to figure out Rails. The idea that I would ever consider letting the middleware have any kind of write access to the database schema seemed so improbable that I spent rather a lot of time looking for the 'other' tutorial, the one where you start with the data and work your way forward to the web site, rather than starting in the middle and working out in both directions.
Migrations can be very useful even if you are doing PostgreSQL specific
DDL (which I am). You can just call execute in the migration with an SQL
string. It's nice to keep changes to app code and data schema version
controlled together.
I eventually figured out that Rails just doesn't work that way. Clearly, the paradigm that it uses is very effective for a lot of people. That's a fine thing; I'm not here to try to convince people that it's doing stuff the 'wrong way.' I just need to find something that supports a more data-centric (and database-centric) approach.

I have an old site I'd like to modernize, and a brand-new site to develop. My pre-existing site is currently using WiTango as the middleware, and I'd love to keep using it, but can't afford the $5,000 non-restricted server license. I've been looking at various non-Rails options, and it looks like, to a certain degree, it turns into a snap-your-own-together situation, where I get to pick a framework (like Merb, Padrino, Ramaze, Nitro, etc.), an adapter (Mongrel, Rack, WEBrick, Thin, etc.), a templating engine (Erubis, Liquid, Haml, Markaby, Radius, etc, etc, etc, etc), and an ORM. Since I'm working from the database out, I'm starting with the ORM, and will then find parts that work well with it.

Not too surprisingly, most explanations and introductions tend to compare the new ORM to what somebody would have been doing in Rails; most people reading those pages will have already worked in Rails. It took me a little while to figure out that most of the information *I* wanted was appearing under the phrase 'legacy database.' I'm not dealing with a 'legacy' database for the new project; I'm still finishing up the work on the PostgreSQL schema. It's brand new, and I'm leveraging Postgres's feature set hard in order to protect the integrity of the data. Composite unique keys, foreign keys, and two different custom datatypes are part of the schema, for example.

ActiveRecord did turn out to have a command available to build its migration file (I think that's what it was) FROM the schema, rather than vice versa. Unfortunately, it only managed to extract about 20% of the tables, because I'm using UUIDs for the primary keys, not sequences or integers, and it didn't know what to do with a UUID. I have no doubt that there is some place, somewhere, where I could define a new database type, but a couple of hours digging and fiddling with various files didn't lead me to the solution.
I think you are referring to schema.rb. You can change environment.rb to
dump to SQL for its schema definitions.

# Use SQL instead of Active Record's schema dumper when creating the
test database.
# This is necessary if your schema can't be completely dumped by the
schema dumper,
# like if you have constraints or database-specific column types
config.active_record.schema_format = :sql

I don't think ActiveRecord itself should have a problem with PostgreSQL
custom data types. It should just treat them as strings.
I did get the distinct impression that, while it was almost certainly possible, it probably wouldn't ever be smooth. I decided it made more sense to try to find an ORM that was more comfortable with the idea it could only reflect the database's schema, rather than trying to make the DB schema conform to Ruby objects.

So far, I've found DataMapper, Friendly, M4DBI, Ohm, and Sequel as possible alternative ORMs, but all the documentation for them is heavy with terminology and jargon from Rails, and usually brags about how I can make tables appear in my database magically from my Ruby objects. Which ORMs are better for connecting to my Postgres databases in a way that will best take advantage of, or at least not get in fights with, the constraints enforced by Postgres itself?
It sounds like you really want a minimal ORM layer that mostly just
stays out of the way. Probably Sequel would be a good place to start
looking.
Thanks for reading to the end of a pretty long message, and thanks even more to those of you who help me figure out where to look for the answers. :)
Jack
 
D

Dave Howell

=20
Migrations can be very useful even if you are doing PostgreSQL =
specific DDL (which I am). You can just call execute in the migration =
with an SQL string. It's nice to keep changes to app code and data =
schema version controlled together.

I don't understand what you're saying here. I can call 'execute' ? Call =
it with what?=20

I did mention, I believe, that under no circumstances will any external =
apps, Ruby included, have any write privileges to Postgres's schema.
I think you are referring to schema.rb. You can change environment.rb =
to dump to SQL for its schema definitions.

Yup, did that right away.=20
=20
config.active_record.schema_format =3D :sql
=20
I don't think ActiveRecord itself should have a problem with =
PostgreSQL custom data types. It should just treat them as strings.

It didn't. it failed to generate them. These are UUIDs coming from the =
OSSP-UUID library.=20
It sounds like you really want a minimal ORM layer that mostly just =
stays out of the way. Probably Sequel would be a good place to start =
looking.

Thanks.=20
 
J

John W Higgins

[Note: parts of this message were removed to make it a legal post.]

Evening Dave,

So far, I've found DataMapper, Friendly, M4DBI, Ohm, and Sequel as possible
alternative ORMs, but all the documentation for them is heavy with
terminology and jargon from Rails, and usually brags about how I can make
tables appear in my database magically from my Ruby objects


I'm surprised you mentioned Sequel in that list because Sequel is very much
non-rails based and I've not seen much mention of rails in the docs at all (
http://sequel.rubyforge.org/). I admit that the quick sample on the home
page does create a table but that is much more in the sense of having a
sample that is self-contained rather then forcing you to do anything at all
in terms of creating the schema within Sequel. You will note that the create
table call is totally non-related to later accessing the table and has
nothing to do with ruby objects - it's simple a method that you can use to
create a table - nothing more nothing less.

I think you'll find Sequel very much to your liking with respect to the fact
that it's heavily based on "datasets" (
http://sequel.rubyforge.org/rdoc/files/doc/dataset_basics_rdoc.html) which
sounds like a concept that you would be rather happy with....

I would very much steer you towards website docs to see if Sequel might just
meet your needs. If you had specific questions once you had a look - the
Sequel mailing list/google group (http://groups.google.com/group/sequel-talk)
is an excellent way to get help. Jeremy is exceptionally responsive to
issues and questions and very much goes the extra mile to help folks out.
Specifically with respect to UUIDs or your custom datatypes - I'm sure you
would find an answer either from the docs or from Jeremy via the mailing
list that will satisfy you. I'm also thinking that it would be very easy to
setup a small test to see how Sequel handled your "interesting" fields.

John
 
W

Walton Hoops

[snip]...[/snip]

"Migrations" really had me mystified when I started trying to figure out Rails. The idea that I would ever consider letting the middleware have any kind of write access to the database schema seemed so improbable that I spent rather a lot of time looking for the 'other' tutorial, the one where you start with the data and work your way forward to the web site, rather than starting in the middle and working out in both directions.

I eventually figured out that Rails just doesn't work that way. Clearly, the paradigm that it uses is very effective for a lot of people. That's a fine thing; I'm not here to try to convince people that it's doing stuff the 'wrong way.' I just need to find something that supports a more data-centric (and database-centric) approach.

But it doesn't. I'm surprised no one has mentioned it yet, but there is
nothing about Rails that forces you to use migrations. Here's a quick
demo of ActiveRecord (the Rails ORM) without migrations:
http://gist.github.com/427016

So assuming you already have a table named 'demos' in your database, you
can just run 'script/generate model demo' and TADA! It works. Or if you
want, you can just create the demo.rb file in your app/models directory
and that will work too.

Now it's true, if you use some the of the generators (such as the model
generator above), they will generate some migrations, but you can simply
*GASP* not run them. Your code will still work fine.
[snip]...[/snip] It's brand new, and I'm leveraging Postgres's feature set hard in order to protect the integrity of the data. Composite unique keys, foreign keys, and two different custom datatypes are part of the schema, for example.
Foreign keys are easy, just look up how to use the associations such as
:has_one and :has_many. Composite keys are a little more difficult, but
there is a plugin for that (http://compositekeys.rubyforge.org/). The
custom data-types are a sticky point. I don't have a Postgre
installation handy, and a quick Google didn't turn up anything in the
way of problems or solutions, so I don't know what may or may not work.
I'd start by using the :class and :methods functions on those columns to
see what you get. I may give it a try later to see what I can come up with.
ActiveRecord did turn out to have a command available to build its migration file (I think that's what it was) FROM the schema, rather than vice versa. Unfortunately, it only managed to extract about 20% of the tables, because I'm using UUIDs for the primary keys, not sequences or integers, and it didn't know what to do with a UUID. I have no doubt that there is some place, somewhere, where I could define a new database type, but a couple of hours digging and fiddling with various files didn't lead me to the solution.

Again, schema.rb (which is what your trying to generate) is COMPLETELY
unnecessary. It's only useful if you want to manage your schema with
Rails. As for UUIDs as PKs, you'll notice in the example above that I
used strings as a PK with no difficulty. UUIDs should work the same way.
I did get the distinct impression that, while it was almost certainly possible, it probably wouldn't ever be smooth. I decided it made more sense to try to find an ORM that was more comfortable with the idea it could only reflect the database's schema, rather than trying to make the DB schema conform to Ruby objects.

So far, I've found DataMapper, Friendly, M4DBI, Ohm, and Sequel as possible alternative ORMs, but all the documentation for them is heavy with terminology and jargon from Rails, and usually brags about how I can make tables appear in my database magically from my Ruby objects. Which ORMs are better for connecting to my Postgres databases in a way that will best take advantage of, or at least not get in fights with, the constraints enforced by Postgres itself?
The only one on this list that I've used with Postgre is sequel, which
may be what your looking for. It is certainly less opinionated than
ActiveRecord. The one issue that I ran into with sequel is that it has
a very poor understanding of schema_search_path so working with multiple
schemas can be annoying.

Hope this helps.
 
E

Edward Middleton

Thanks for reading to the end of a pretty long message, and thanks
even more to those of you who help me figure out where to look for the
answers. :)

Get a copy of "Patterns of Enterprise Application Architecture"[1] read
and grok that first. If you are just confirming your model to your
database you don't need objects. They will just be a distraction ;)

Well, I'm going to need *something* to hand over to the templating engine in order to build web pages.

I am in no way advocating you do it this way but if you are going to
throw away all the advantage of using a good domain model[1] then you
may as well just pass data to your templating engine. Postgresql has a
driver ruby-pg[2], thats probably what you want.

Edward

1. http://martinfowler.com/eaaCatalog/domainModel.html
2. http://bitbucket.org/ged/ruby-pg/wiki/Home
 
M

Mike Stephens

Dave said:
For my work, the data is the supreme treasure, and the database engine is the
god-emperor.
You're spot on, Dave. ORMs are the Devil's spawn. Stay well clear.
 
P

Phrogz

"Migrations" really had me mystified when I started trying to figure out Rails.
The idea that I would ever consider letting the middleware have any kind of write
access to the database schema seemed so improbable [...]

You can use a migration that speaks raw, engine-specific SQL to the
DB, and still have the benefit of migrating up and down.
I've been looking at various non-Rails options, and it looks like, to a certain degree,
it turns into a snap-your-own-together situation, where I get to pick a framework [...]
an adapter [...] a templating engine [...], and an ORM.

I personally recommend Sinatra, Haml, and Sequel as the foundation,
with Thin and Nginx as deployment details.

(To lend some credence to my recommendation, I've been doing web
development since 1994, professionally since 1996, and used beyond the
level of experimentation: VBScript ASP, JScript ASP, ASP.NET, Rails,
Ramaze, Sinatra with hand-rolled ORMs, ActiveRecord and Sequel,
deployed on IIS, Apache, Webrick, Mongrel, Thin, backed by MSSQL,
SQLite, and PostgreSQL.)
I decided it made more sense to try to find an ORM that was more comfortable with the idea
it could only reflect the database's schema, rather than trying to make the DB schema
conform to Ruby objects.

Reflecting convention-over-configuration thinking, Sequel requires the
least amount of work (no configuration) when your design matches what
it expects, but you have the ability to customize table names, PKs, FK
columns, etc. to match your setup.

I've not yet had a schema that I couldn't map nicely to reasonable
objects, though I'm often designing with the ORM in mind instead of
mapping a completely legacy schema.

Sequel's maintainer (Jeremy Evans) seems a big fan of PostgreSQL, is
quite knowledgeable on deep DB concetps, and (both at the moment and
for years now) has been incredibly responsive and helpful.

I find Sequel's documentation excellent, and yet that seems to be
considered its weakest point at the moment (and undergoing additional
and substantial improvement). The only area that I've personally felt
the documentation was 'deficient' is that the introductory
documentation makes it appear that Datasets are the primary intended
way of working with data, with Models and ORM an afterthought. I call
this 'deficient' because it is not the case: Sequel's Models are fully
supported, first-class, and powerful.

I encourage you to give Sequel a long, hard investigation before
discounting it.
 
D

Dave Howell

=20
I encourage you to give Sequel a long, hard investigation before
discounting it.

Oh, believe me, Sequel has never been 'discounted.' Just my own digging =
had Sequel as one of the three top candidates on my list.=20



=20
I am in no way advocating you do it this way but if you are going to
throw away all the advantage of using a good domain model[1] then you
may as well just pass data to your templating engine. Postgresql has = a
driver ruby-pg[2], thats probably what you want.

I've got a number of scripts already that drive data in and out of =
Postgres 'directly,' but I've been assuming that once I add a templating =
engine and web adapter, that they'll be much easier to use if I'm giving =
them Ruby objects that look like what ORMs make, rather than a big array =
or some such.=20

I still haven't figured out what, exactly, a Domain Model will do for =
me, or even exactly what it is, but I'm not (deliberately? consciously?) =
trying to throw those advantages away. Thanks for the links.



So assuming you already have a table named 'demos' in your database, = you
can just run 'script/generate model demo' and TADA! It works. =20

Except that it didn't. I tried that, but I just ended up a bit sad and =
rather puzzled.=20
Or if you
want, you can just create the demo.rb file in your app/models = directory
and that will work too.

Er, OK. But **how**? Everything I've found just assumes I'll use the =
magic script command to make it. Nothing tells me "here's how you'd =
build one by hand, if you were so crazy that you'd want to do it that =
way."
As for UUIDs as PKs, you'll notice in the example above that I
used strings as a PK with no difficulty. UUIDs should work the same =
way.

I've thought so, too. But I just ended up with a whole lot of "Could not =
create table blahblahblah. Unrecognized data type UUID." messages in the =
file. I'd post it verbatim, but I'm afraid I've already wiped the test =
folder and de-installed Rails.=20


I'm surprised you mentioned Sequel in that list

[of things with Rails-centric documentation]
because Sequel is very much
non-rails based and I've not seen much mention of rails in the docs at = all (
http://sequel.rubyforge.org/). I admit that the quick sample on the = home
page does create a table but that is much more in the sense of having = a
sample that is self-contained rather then forcing you to do anything = at all
in terms of creating the schema within Sequel.=20

I was probably overly broad in my characterization. I believe, actually, =
that I read through the Sequel documentation fairly early in my =
research, and ran across the "how to make a table in your database from =
within Sequel," did NOT find a "how to make Sequel construct an object =
FROM your table" as easily, and moved on to some of the other candidates =
in the list just because I was trying to learn a little bit about =
everything first. While creating a table in the DB from an object isn't =
intrinsic to Rails, it does reflect the object-centric (vs. =
database-centric) perspective that keeps coming between me and the =
information I really want to find.=20

So: lots of votes for Sequel. I am installing the gem even as I write =
this.

Thank you all, and for the sake of posterity, archiving, and others who =
might come along later wondering the same thing, I'll do a follow-up =
post with the results.=20
 
W

Walton Hoops

How did it not work? I guarantee something happened. My guess would
that you didn't set the schema_search_path correctly in your
'config/database.yml' file so it couldn't find the table, but without an
error message that is just a guess based on the kind of mistake I would
make.
You're probably right, everything assumes you will learn by following
the tutorials or books, which believe it or not do show you how to edit those files manually. That said, all you need to put in that demo.rb file for the basic functionality is:

class Demo < ActiveRecord::Base
end

Of course that assumes a few things, for example that you have a table
named 'demos'. If you want to break that convention you'd have to look
up how (in this case via :table_name function), but even using the magic
scripts you'd have to look that up.

That is the kind of error you get running a database migration. Again,
you DO NOT need to run ANY migrations to use Rails.

It sounds to me like you never really understood how Rails actually
worked and that's at least half the problem. That said there is nothing
wrong with just writing a data access layer over your database (or using
Sequel/ActiveRecord/GenericORMHere) and providing it to a web app
written in Sinatra or something similar. In fact, given that you have a
pre-existing database that likely violates many of Rails conventions
that may be the best way to go.

If you do decide to give Rails another look I'm sure you'll find plenty
of people willing to help on the Rails list.
 
E

Edward Middleton

I am in no way advocating you do it this way but if you are going to
throw away all the advantage of using a good domain model[1] then you
may as well just pass data to your templating engine. Postgresql has a
driver ruby-pg[2], thats probably what you want.

.. but I've been assuming that once I add a templating engine and web
adapter, that they'll be much easier to use if I'm giving them
Ruby objects that look like what ORMs make, rather than a big array
or some such.

I think you might be underestimating the difficult/complexity of faking
a domain model and overestimating the advantage gained from the various
template helper functions, as always YMMV.
I still haven't figured out what, exactly, a Domain Model will do for me,
or even exactly what it is, but I'm not (deliberately? consciously?)
trying to throw those advantages away. Thanks for the links.

Well it should make having an object model useful rather then a
distraction.

Edward
 
D

Dave Howell

I explained this a bit more in my original message:=20
ActiveRecord did turn out to have a command available to build its =
migration file (I think that's what it was) FROM the schema, rather than =
vice versa. Unfortunately, it only managed to extract about 20% of the =
tables, because I'm using UUIDs for the primary keys, not sequences or =
integers, and it didn't know what to do with a UUID. I have no doubt =
that there is some place, somewhere, where I could define a new database =
type, but a couple of hours digging and fiddling with various files =
didn't lead me to the solution.=20
edit those files manually.

It seemed likely that the information existed. However, I am NOT sure =
that it existed somewhere other than in the core documentation. And the =
core documentation was quite incomprehensible. Like 95% of all the =
RDoc/ri information on my computer, it's organized for reference: to =
give you the details about a particular part of the library or module. =
If you don't know *which* command you want in the first place, or if =
you're trying to do something that isn't a function of a single command, =
then you can't just 'find' it in the reference documents.=20

In order for me to figure it out from the primary documentation, I would =
first have to have a good solid understanding of how Rails works, and =
where it puts things. I would have to work through all the tutorials and =
build a bunch of little sample websites. Then I might be able to figure =
out how to do what I wanted to do, and whether or not it would do =
*everything* I required, or only *some* of it.=20

Or, I could ask people who already had that knowledge, and save myself =
many hours of work. {smile}

Again,
you DO NOT need to run ANY migrations to use Rails.

To use it? No. But I didn't need to 'use' it. I needed to evaluate it. =
To evaluate it, I needed to work through a tutorial or two, but with MY =
data. And I could not find *any* information designed to introduce me to =
Rails that did not take for granted that there was *no* pre-existing =
data, because that's very much how Rails expects you to work: you build =
the database from Rails. There were a few bits of info here and there =
that hinted at how to build a migration file from an existing database, =
but because Rails (or ActiveRecord, or whatever component was in charge =
of this part) failed to handle my UUID primary keys, it didn't work.=20
It sounds to me like you never really understood how Rails actually
worked and that's at least half the problem.=20

No, actually, I'm pretty sure I understood all too well how Rails works.=20=


A gentleman named William Pietri commented in a blog post by Derek =
Sievers "Treating the database as the main focus, rather than an =
implementation detail is, from the Rails perspective, the wrong =
approach. And Rails is very opinionated software; it does its thing =
well, but if you want it to do something else, it's not a good match."=20=


This was exactly what I had already concluded. As long as I was doing =
things "the Rails way" stuff happened almost magically. As soon as I =
veered off the path, I was fighting for every inch of progress.

{search search search}

Aha! Something new! Somebody actually has a blog entry for "Ruby on =
Rails: UUID as your ActiveRecord primary key"

=
http://ariejan.net/2008/08/12/ruby-on-rails-uuid-as-your-activerecord-prim=
ary-key/

"[rake db:schema:dump] does not look at the id column in your database, =
but instead adds the default primary key definition from the =
ActiveRecord adapter. The solution is to disable the id column and =
create a primary key column named uuid instead."

As per a number of other Rubyist's recommendations, I've installed =
Sequel. Sequel *does* look at my database and automatically respects =
what the db defines as the primary key. (It isn't clever enough to =
automatically adopt the pre-existing *foreign* key constraints, but I'm =
willing to live with that.)

Let me repeat at this point: I am NOT here to try to slam Rails, or =
ActiveRecord, or such. I'm sure they're very popular for very good =
reasons. People have made some pretty amazing sites in preposterously =
short time spans with them. I just felt that my particular situation was =
probably not one of them.
That said there is nothing
wrong with just writing a data access layer over your database (or = using
Sequel/ActiveRecord/GenericORMHere) and providing it to a web app
written in Sinatra or something similar. In fact, given that you have = a
pre-existing database that likely violates many of Rails conventions
that may be the best way to go.

Interesting turn of phrase. "Violates many of Rails conventions." =
Indeed. "Fails to subscribe to Rails' orthodoxy" might be another way to =
phrase it.=20

I actually used to have all my primary keys' names like 'product_id" in =
table 'products' in anticipation of using Rails with it one day, but I =
got tired of dealing with underscores, and stripped them out. Because =
that's really at the heart of my search for an alternative to Rails. =
It's not actually a pre-existing database. I can still rewrite the =
schema as I see fit. I *could* start from scratch, build the database =
from within Rails, then import the data from its present true purgatory =
in a badly-designed Access database. However, too many of the defaults =
and assumptions in Rails are ones that I'm not willing to accept.=20

It's hard (for me) to tell what one really can do, or do easily, in =
ActiveRecord because there's so many posts on the web that are out of =
date. Is support for foreign keys built into it yet, or is it still an =
optional module? I'm not sure. But I'm sure that I don't want an ORM =
that *can* present a complete model of my data, I want one that *wants* =
to.=20
 
D

Dave Howell

I think you might be underestimating the difficult/complexity of = faking
a domain model and overestimating the advantage gained from the = various
template helper functions, as always YMMV.

That's quite possible. Er, 'faking' a domain model? I'm not even sure =
what that means. {off to Wikipedia...}

Ah. I don't think I'm trying to 'fake' that. I am putting in tremendous =
effort to ensure that the data and relationships in my database are as =
accurate and complete a model of how the information flows between the =
various departments and members of the corporation for whom I'm working, =
as possible. I certainly hope to have the Ruby components reflect that =
as well.=20

On the other hand, I cannot imagine that I could possibly *over*estimate =
the advantages that a modern templating engine can give me. My baseline =
is Tango 3, which dates from 1996. Before that, I build a whole website =
with .idc/.htx file pairs in IIS, which was before Microsoft had =
invented Active Server Pages.=20

=
http://www.thefreelibrary.com/EveryWare+Releases+the+Windows+beta+version+=
of+Tango%3B+EveryWare...-a018391130

God help us all if Haml, et al, can't do any better than that.=20
 
E

Edward Middleton

That's quite possible. Er, 'faking' a domain model? I'm not even sure
what that means. {off to Wikipedia...}

The wikipedia page isn't particularly useful. Martin Fowlers web page is
better, i.e.

"An object model of the domain that incorporates both
behavior and data."

and there is a reasonable explanation in EAA[1].
Ah. I don't think I'm trying to 'fake' that. I am putting in tremendous
effort to ensure that the data and relationships in my database are as
accurate and complete a model of how the information flows between the
various departments and members of the corporation for whom I'm working,
as possible. I certainly hope to have the Ruby components reflect that
as well.

Well a domain model is pretty much that plus behavior but starting from
an object model and then mapping to a database.

Edward

1.
http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420
 
R

Richard Conroy

[Note: parts of this message were removed to make it a legal post.]

Oh, believe me, Sequel has never been 'discounted.' Just my own digging had
Sequel as one of the three top candidates on my list.

I have looked at Sequel myself and it does seem very compatible with your
needs.
There is also the Ruby database connectivity library DBI (IIRC part of the
standard lib),
which is just a basic database connectivity/SQL library. However Sequel
seems to
have superceded in common use.

I've got a number of scripts already that drive data in and out of Postgres
'directly,' but I've been assuming that once I add a templating engine and
web adapter, that they'll be much easier to use if I'm giving them Ruby
objects that look like what ORMs make, rather than a big array or some such.

Well not necessarily. Type conversion (between SQL data types & Ruby, or any
language for that matter) is a necessary part of any DB communication. Ruby
is dynamically typed, so each ORM/DB connectivity API has a lot of options
in this regard. For instance ActiveRecord builds up/completes your models by
inspecting your DB. In practice the more popular APIs tend to have fairly
array-like or intuitive type conversion.

I still haven't figured out what, exactly, a Domain Model will do for me,
or even exactly what it is, but I'm not (deliberately? consciously?) trying
to throw those advantages away. Thanks for the links.

Having model objects saves a LOT of coding. It gives you intuitive places
to put validation. It integrates well into testing apis and makes the client
side coding very tidy and natural. In addition you can get a lot of free
features if you use an API like DM or AR (like SQL injection protection, or
form helpers). Do not underestimate the saving in lines of code.

regards,
Richard
 
E

Edward Middleton

Having model objects saves a LOT of coding. It gives you intuitive places
to put validation. It integrates well into testing apis and makes the client
side coding very tidy and natural. In addition you can get a lot of free
features if you use an API like DM or AR (like SQL injection protection, or
form helpers). Do not underestimate the saving in lines of code.

The problems occur when you go from a database schema to a domain model.
All the major ORM frameworks are built on the assumption you will
confirm the database to the domain model, not the other way round. i.e.
Object Relational Mapping not Relational Object Mapping ;)

Legacy database mapping is hard and not something you should do unless
really necessary. i.e. you don't control the database and so can't chose
a reasonable schema.

Edward
 
B

Brian Candler

Dave said:
I actually used to have all my primary keys' names like 'product_id" in
table 'products' in anticipation of using Rails with it one day, but I
got tired of dealing with underscores, and stripped them out.

Aside: Rails (or ActiveRecord) expects that the primary key is called
"id".

Now, I've written applications which connect ActiveRecord to an existing
legacy database which doesn't respect Rails conventions, and they work
fine. For example, if I want a model class called Playlist then AR will
normally assume a table called "playlists" and a primary key of "id",
but these are easily overridden:

class Playlist < ActiveRecord::Base
self.table_name = 'venue_playlist'
self.primary_key = 'plt_id'

# Similarly for foreign key relations
has_many :playlist_items, :foreign_key => 'pli_playlist_id',
:eek:rder => 'pli_order', :dependent => :delete_all
end

I'm not 100% sure how well AR copes with a non-numeric primary key, but
I believe it's OK. Once you define the primary key explicitly, it no
longer tries to auto-assign it from a sequence, as far as I remember. So
you'll have to remember to set it explicitly when creating new
objects/rows.

Where AR really falls down is when you have a composite primary key.
ISTR I came across some plugin for this, but I've never tried it.
Because
that's really at the heart of my search for an alternative to Rails.
It's not actually a pre-existing database. I can still rewrite the
schema as I see fit. I *could* start from scratch, build the database
from within Rails, then import the data from its present true purgatory
in a badly-designed Access database. However, too many of the defaults
and assumptions in Rails are ones that I'm not willing to accept.

You really don't need to use migrations in Rails/AR. Trust me, I know.
The DBA team I work with won't let me have schema-level access to any
production database, so I have to provide them with SQL scripts which
they run manually to make schema changes.

Hence the app itself just reads the column definitions from the DB and
builds its object accessor methods from that; it cannot and does not
push out any schema modifications.

So I'd say:
* design and build your database how you want
* connect ActiveRecord to it as above
* watch it work
* if you really get stuck, then look at other ORMs (but I can't vouch
how well they will work with the rest of Rails, at least before Rails 3)

Regards,

Brian.
 
B

Brian Candler

Brian said:
class Playlist < ActiveRecord::Base
self.table_name = 'venue_playlist'
self.primary_key = 'plt_id'

# Similarly for foreign key relations
has_many :playlist_items, :foreign_key => 'pli_playlist_id',
:eek:rder => 'pli_order', :dependent => :delete_all
end

And for reference, here's the relation from the other side:

class PlaylistItem < ActiveRecord::Base
self.table_name = 'playlist_item'
self.primary_key = 'nonexistent'
belongs_to :playlist, :foreign_key=>'pli_playlist_id'
end

Notice that this particular table didn't really have a primary key as
such; each row was a unique tuple. Setting the primary_key to
'nonexistent' just proves that AR never attempted to use it.

At the controller side, all I needed to do was to set the attributes I
was interested in when creating the object.

def add_item
...
PlaylistItem.create!(
:pli_playlist_id => @playlist.plt_id,
:pli_track_id => ...
:pli_order => ...
)
...
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top