How should Ribs definitions look?


I am currently sitting with Ribs, trying to decide how the definitions for associations should look like. I’ve also decided that I don’t want to use the current scheme for properties either. I also have some interesting constraints. First, I do not want to evaluate the block using instance_eval, so introducing nice method_missing hooks in the block context is out (so I can’t do anything like “has n” as DataMapper). Also, all definitions need to be able to take additional parameters in a hash. So something like “rib.has * :Posts” won’t work either.

I have come up with something that I’m reasonably happy with. It’s quite terse but definitely readable. It doesn’t pollute any namespaces. And hopefully it will only be used when the model need to differ from the conventions. I’m thinking about taking conventions a step further with Ribs and automatically try to figure out associations based on naming and foreign keys – but I haven’t decided about that yet.

All of these examples are supposed to be executed inside the Ribs! block, with r being the Rib parameter. I’ve decided to allow the table name as a parameter to the Ribs! method call instead of being something you set inside.

First of all, setting which property/properties are a primary key, I’m thinking about one or more of these alternatives – where track_id is the property name:

r.track_id :primary_key
r.track_id :primary_key => true
r.track_id = :primary_key
r.track_id.primary_key!

I’m skittish about the track_id= alternative, but the others I think can coexist quite well.

The next thing is to handle the mapping from one property name into a different column name (if no column name is specified, the property name will be used, of course):

r.title :column => :track_title
r.title.column = :track_title

Nothing very extraordinary here. I would probably like to have both alternatives here.

The next one is more interesting. I haven’t yet decided how to handle specifying primitive types. This code is supposed to handle the case that in ActiveRecord are covered with has_one and belongs_to. I don’t really see why they have to be different, really, so I’m thinking about doing something like this:

r.blog :is_owner
r.blog :is => Blog

I’m skittish about :is_owner, but it also feels slightly icky to have to specify the type of all single associations. This is definitely an area I would like to have some good ideas about.

Finally we come to the one-to-many and many-to-many associations. What makes this different is that I can have both a Set and a List (and also Map) since Hibernate handles these for me:

r.comments :list_of => Comment
r.comments :set_of => Comment
r.comments :is_set
r.comments :is_list

Once again I’m not sure how to handle it in such a way that you don’t have to write the name of the other entity in all definitions.

Anyway, this is what I currently have. I would appreciate innovative ideas here – especially if they are innovative within the constraints I’ve set for myself.



Ribs available from Gems


Ribs is now available from Gems. You can install it using this command:

jruby -S gem install ribs

Much pleasure, and do give your comments and ideas to me.



Announcing Ribs 0.0.1


I am extremely pleased to announce the first release of Ribs.

Ribs is a library for JRuby, that allows you to persist Ruby objects using Hibernate. Some time ago I wrote about ActiveHibernate. I have now decided to implement this myself, and the result is the Ribs project.

The first release is quite minimal in scope. You can define and work with models that have primitive values only – there is no support for associations. You can find, create, update and delete model objects. All of this uses Hibernate and JDBC.

To get started, you just define that an object is to be a Ribs model:

class Artist
  Ribs!
end

Once that’s done, you can start working with it.

Of course, this is just the beginning. I have a quite long list of things I’d like to have in the project, but I felt the need to release quickly and often to be more important than to implement everything first.

This release is not really for production usage, but I would appreciate if people tried it out and came with suggestions. The current planned features can be found in the PLAN file, in the git repository.

More documentation can be found here: http://olabini.com/projects/ribs/doc.
You can download the gem at: http://olabini.com/projects/ribs/downloads/ribs-0.0.1.gem.
The git repository is at: git://github.com/olabini/ribs.git.

Ribs will soon be available in the regular gem repositories – as soon as my Rubyforge project has been approved.

The project is released under the MIT license.