Ruby/rails port of Cocoon/hibernate

Hi, I'm currently running an apache/jboss cocoon/flow/hibernate/ajax paypal (directpayment) project and am looking into the possibility of porting it across to ruby/rails. For that reason I would like to know the following:

1. Can I call my java classes or would I be looking at a complete rewrite in ruby? 2. How effective is ruby in terms of seperation of concerns regarding design from content? 3. I have a number of hibernate maps accessing various postgresql tables. Can I reverse engineer those tables into rails (maps?) ? 4. In cocoons mvc (flowscript) it is possible to instantiate and call class methods from within the document at the same time as directing flow. Is this possible in ruby/rails?

Ok, to start with, I don’t really understand what #4 means, but I think I can address the other well enough: #1: If the application is fairly complex, you’d probably be looking at a full re-write… however, there is a project called JRuby that is attempting to change that statement. It allows you to run Ruby scripts on the JVM, and it allows you to reach out to existing Java code and call things in it… however, it’s support for Rails isn’t 100% atm… it can do basic stuff, moving on up into intermediate, but extremely complex code is better left outside of JRuby atm.

#2: Excellent. It is on par with the best of any other framework I have ever known in this regard. #3: Using Rails, you generally don’t have to do much of anything to support already existing tables… Rails just reads in the schema info from the DB, and auto-generates all kinds of nifty things for you… the minor exception to this is that if you aren’t using the default names that Rails likes in your DB (it wants the primary key auto-increment id field to be named id, etc) you have to specify them in your file like so: class User < ActiveRecord::Base set_primary_key “userid” end

Many people find On LAMP’s Rolling with Ruby on Rails tutorial a great place to find out what Rails can offer: the revisited tutorial is particularly good in this respect:

http://www.onlamp.com/pub/a/onlamp/2006/12/14/revisiting-ruby-on-rails-revisited.html

Hi Luke, many thanks for the information you have provided thus far.

In regards to my question 4, an example might suffice: (myArtistDetails.js)

importClass(Packages.test.Artist); Flows equivalent of package test; import Artist;

function artistDetails() {

try {
    artistID = cocoon.parameters.artistID;//either use defined or specified from dB
    artist = Artist.getArtist(artistID); //Artist id passed into class method

   
    artist_name = artist.getArtistName();//artist name is obtained from the Artist class
    artist_info = artist.getArtistInfo();// as above
   
}catch(e) {
}

cocoon.sendPageAndWait("artistDetails2.xml",{"artistID":artistID,"artist_name":artist_name,"artist_info":artist_info}); //MVC: flow is directed to rtistDetails2.xml with associated values

}

In the above flow (MVC) document a java class is imported, its method interrogated and corresponding values passed onto the next document in line. How would this be handled in Ruby/Rails, such that an action on a web page causes artistDetaills() to be called and then directed on to artistDetails2.xml?

Am I correct in thinking that rails is a mapping technology much like hibernate?

It can be used as such, although I’m not sure that I would call that it’s default application. And you could do exactly what you’re asking using AJAX and Rails’s links to it… it is one of the major aspects of Rails that promotes it above and beyond most of the other frameworks available… you could even have it load up the artistDetails2.xml file into the page it’s already on, instead of directing them to yet another page.

Hi Andrew,

I come from a JBoss/J2EE/Java background and I have been working on my first RoR project for the last several months... all-in-all it is a pleasure! If you are new to RoR, it will take a bit to get used to the syntax but once you do, it is amazing how quickly one can get things done and do it in a structured, test-oriented way.

RoR has ActiveRecord that is analagous to Hibernate or EJB3. It supports many of the features and maps relationships nicely. Some of the features I don't see (someone please correct me if I am wrong) are: - lazy-loading/eager-loading ability - object caching (like JBoss Cache)

In your situation, I wonder, rather than do a total immediate rewrite, seeing you are using JBoss, why not keep JBoss as your object/db broker with Hibernate and extend it out using Web Services and call that from a RoR front-end? That way, you could migrate slowly rather than wholesale.

Scott

Hi Scott, my appetite is definitely being whetted!! Please see my replies below:

I come from a JBoss/J2EE/Java background and I have been working on my first RoR project for the last several months… all-in-all it is a pleasure! If you are new to RoR, it will take a bit to get used to the

syntax but once you do, it is amazing how quickly one can get things done and do it in a structured, test-oriented way.

From the various docs and examples I have seen it definitely does seem like a quick development environment!

RoR has ActiveRecord that is analagous to Hibernate or EJB3. It supports many of the features and maps relationships nicely. Some of

the features I don’t see (someone please correct me if I am wrong) are:

  • lazy-loading/eager-loading ability
  • object caching (like JBoss Cache)

OK! I am using hibernate with ehcache handling lazy object caching. Can anyone else confirm whether ActiveRecord supports lazy-loading/object caching?

In your situation, I wonder, rather than do a total immediate rewrite, seeing you are using JBoss, why not keep JBoss as your object/db

broker with Hibernate and extend it out using Web Services and call that from a RoR front-end? That way, you could migrate slowly rather than wholesale.

Great idea! I will look into this as a viable option.

The five main areas of concern to me are as follows:

  1. Database. I am using postgreSQL 8.1. Would rails be able to reverse engineer the required ActiveRecord maps from the dB schema? From what I understand of rails convention table names need to be pluralized. How would the reverse engineering process handle the fact that none of my table names are pluralized?!

  2. Form validation I am using Ajax to handle all form validation in cocoon. In cocoon form dev/validation would be handled by:

a. Specifying that you wish Ajax to handle validation as so:

<ft:form-template action=" login.kont" name=“Form1” method=“POST” ajax=“true”>

b. Defining your form widgets in a seperate document as so: <ft:widget id=“password”>

                                  <fi:styling size="30" type="password" class="keyinbox" style="background-color:#C9C4BD;" />
                              </ft:widget>

c. Defining your validation, against your widgest, in another document as so:

     <fd:field id="password" required="true">
      <fd:datatype base="string"/>

      <fd:validation>
        <fd:length min="5" max="20"/>
      </fd:validation>
     </fd:field>
  1. Paypal API.

I have recently come across a ruby/rails Paypal (directpayment api) so this area is covered.

  1. Image handling.

All artist images are stored in postgresql and read into the webapp as svg via Base64. Cocoon then allows for an svgTOpng or svgTOjpeg conversion before the image is rendered to the page. As an example I have various img calls defined as such:

So in effect the img tag is making a call to the database which in turn return the appropriate binary information, holds it in svg format before converting it to either PNG or JPEG. How would ruby/rails handle this?

  1. Email/Zip I have a process where by the artist track files (mp3) a user may have ordered are pulled out from their order/order_items object, read in the file system directory and then zipped up. This zip is then emailed to the user. How would ruby/rails handle this process?

My personal experience with Cocoon / JBoss / etc tells me to NEVER just port code from these frameworks to Rails. Rewrite the application in Rails, from scratch, redoing even the database if you are allowed to. The end result will be a pure-Rails site, which is vastly easier to develop and maintain than any Java solutions have ever been or will ever be. If you go trying to copy the way said Java solutions do things, you will end up with an unmaintainable mess, if you finish it at all. Rails works best when you let Rails do what it wants to do.

As for specific answers:

  1. Look into RJS. This acts much in the same way as what Cocoon seems to do, defining partials of HTML code that get pushed to the client.

  2. Check out the fleximage plugin: http://agilewebdevelopment.com/plugins/fleximage Should take care of all your needs with this.

Jason

Hi Andrew,

I come from a JBoss/J2EE/Java background and I have been working on my first RoR project for the last several months… all-in-all it is a pleasure! If you are new to RoR, it will take a bit to get used to the

syntax but once you do, it is amazing how quickly one can get things done and do it in a structured, test-oriented way.

RoR has ActiveRecord that is analagous to Hibernate or EJB3. It supports many of the features and maps relationships nicely. Some of

the features I don’t see (someone please correct me if I am wrong) are:

  • lazy-loading/eager-loading ability

Eager loading, sure. You can put :include => blah on either your associations or in the actual find calls to eager load whatever you need.

Lazy loading: By default, associations are lazy loaded. You can change this behaviour as stated above. There is no way, that I know of, to lazy load individual fields (other than doing something like using a view to get a copy of the table that doesn’t have the fields, then doing direct sql queries to get the field in question).

  • object caching (like JBoss Cache)

For this one, you can easily use memcache… Rails is set up to work excellently with it, and there’s a lot of great help around to get you set up… it’s not exactly a Rails piece, but has been tightly integrated.

Also, in the current working version of Rails (called edge rails), all actions (read: functions that you call that generally end up rendering the html to the user) are cached by default… two identical queries will result in only one trip to the DB.

OK! I am using hibernate with ehcache handling lazy object caching. Can anyone else confirm whether ActiveRecord supports lazy-loading/object caching?

See my other message

  1. Database. I am using postgreSQL 8.1 . Would rails be able to reverse engineer the required ActiveRecord maps from the dB schema? From what I understand of rails convention table names need to be pluralized. How would the reverse engineering process handle the fact that none of my table names are pluralized?!

Easy: you can tell your models specifically what table name to use, and it will just go ahead and use them. In essence, you create a model… say you have a person table, and you want a Person model.

class Person < ActiveRecord::Base set_table_name ‘person’ end This will still draw in all your fields automatically and create accessors for them and etc… one other want to consider is the id field… Rails wants it to be named just flat out ‘id’, but a lot of people do something like ‘person_id’… you can use set_id_field

  1. Form validation I am using Ajax to handle all form validation in cocoon. In cocoon form dev/validation would be handled by:

a. Specifying that you wish Ajax to handle validation as so:

<ft:form-template action=" login.kont" name=“Form1” method=“POST” ajax=“true”>

b. Defining your form widgets in a seperate document as so: <ft:widget id=“password”>

                                  <fi:styling size="30" type="password" class="keyinbox" style="background-color:#C9C4BD;" />
                              </ft:widget>

c. Defining your validation, against your widgest, in another document as so:

     <fd:field id="password" required="true">
      <fd:datatype base="string"/>

      <fd:validation>
        <fd:length min="5" max="20"/>
      </fd:validation>
     </fd:field>

Ajax + Rails = super, super, super easy.

  1. Paypal API.

I have recently come across a ruby/rails Paypal (directpayment api) so this area is covered.

Definitely look into Active Merchant: it does Paypal and a TON of other stuff… so if you switch, you’re still covered.

  1. Image handling.

All artist images are stored in postgresql and read into the webapp as svg via Base64. Cocoon then allows for an svgTOpng or svgTOjpeg conversion before the image is rendered to the page. As an example I have various img calls defined as such:

So in effect the img tag is making a call to the database which in turn return the appropriate binary information, holds it in svg format before converting it to either PNG or JPEG. How would ruby/rails handle this?

You completely got me on this one… I’m sure it’s probably possible, but I don’t have a clue.

  1. Email/Zip I have a process where by the artist track files (mp3) a user may have ordered are pulled out from their order/order_items object, read in the file system directory and then zipped up. This zip is then emailed to the user. How would ruby/rails handle this process?

ActionMailer is your friend… ruby comes with standard zipping stuff built in, and ActionMailer is EXTREMELY easy to use to mail.

Hi jason,

My personal experience with Cocoon / JBoss / etc tells me to NEVER just port code from these frameworks to Rails.

Yes, I agree whole heartedly! I’m just trying to ascertain what what technology within the ruby/rails framework will allow me to achieve the same functionality as I currently have with the cocoon/hibernate framework

  1. Look into RJS. This acts much in the same way as what Cocoon seems to do, defining partials of HTML code that get pushed to the client.

I will look into RJS.

  1. Check out the fleximage plugin: http://agilewebdevelopment.com/plugins/fleximage Should take care of all your needs with this.

The plugin looks fantastic. Thanks for that headsup!

Hi Luke, you are a diamond my friend!

All I need to know now is what is the best resource/documentation available in terms of hooking together a ruby/rails/ajax/rjs/activerecord project? Is there a ruby/rails/ajax/rjs/activerecord for dummies type publication available?

One further question if I may, in terms of persisting an objet retrieved from a dB table? Currently I retrieve the hibernate dB object and store it in a session object. I take it that ruby/rails/activerecord would function in much the same way?

I just came across some activerecord code:

class Order < ActiveRecord::Base
     has_many :items
end

That’s it?! One line of code to setup a one-to-many relationship between an order and order items table?!!! :wink:

Hi Luke, you are a diamond my friend!

All I need to know now is what is the best resource/documentation available in terms of hooking together a ruby/rails/ajax/rjs/activerecord project? Is there a ruby/rails/ajax/rjs/activerecord for dummies type publication available?

You'll want the Agile Web Development with Rails book from the Pragmatic Programmers. IT covers all the technologies plus a lot more and also contains a very useful reference to the rails framework.

--max

One further question if I may, in terms of persisting an objet retrieved from a dB table? Currently I retrieve the hibernate dB object and store it in a session object. I take it that ruby/rails/activerecord would function in much the same way?

Yes, you can do that. However it's of course better pracice not to store any application state (even temporary) in the session.

I just came across some activerecord code:

class Order < ActiveRecord::Base has_many :items end

That's it?! One line of code to setup a one-to-many relationship between an order and order items table?!!! :wink:

Yes! And if you like that one, wait until you find out about the really cool stuff :wink:

--max

That’s it?! One line of code to setup a one-to-many relationship between an order and order items table?!!! :wink:

You’d probably also want another line of code to do the other half of the mapping:

class Item < ActiveRecord::Base

belongs_to :order

end

So, two lines of code. Terrible, ennit.

  • donald

Hi Max,

You’ll want the Agile Web Development with Rails book from the

Pragmatic Programmers. IT covers all the technologies plus a lot more and also contains a very useful reference to the rails framework.

thanks for that recommendation. I will look it up.

Hi Donald,

class Item < ActiveRecord::Base

belongs_to :order

end

Stop it! When I think how long it took me before I got a handle on hibernate map/classes!!!

2 lines?! It’s just not right!!! :wink:

I love that everyone moving from a different framework (with the possible exception of things like Django) has these moments: the “oh my god it’s so easy” ones.

You want to see something freaking amazing?

I also like the two-line ajax autocompletion:

in the view:

<%= autto_complete_field :user, :name %>

in the controller:

auto_complete_for :user, :name

Done.

Some of the plugins do amazing things too, such as acts_as_versioned. One line of code to get a complete versioned history of every update to a model, complete with rollback to a previous version. The code?

class WikiPage << ActiveRecord::Base   acts_as_versioned end

and then

wiki_page.revert_to(wiki_page.version-1) # get previous version

:wink:

--max

there is no equivalent to the Cocoon flowscript (with the continuations and all).. not that its a blocker, just be aware that coding forms is different :slight_smile:

-pete

I love that everyone moving from a different framework (with the possible exception of things like Django) has these moments: the "oh my god it's so easy" ones.

Yeah. I was excited when EJB3 came out after years of EJB2/xDoclet. Now, I won't even consider working on anything except RoR. Unless, I get paid enough, of course. :wink:

You want to see something freaking _amazing_? This is code I wrote on this list the other day, and it just flipped my lid that it was so easy to do this. Say you want a tree of categories. such that you have a parent with multiple children, who can have multiple children, etc.

First, if you want the super easy route, do this class Category < ActiveRecord::Base   acts_as_tree end

and put the field "parent_id" in your table... and you're done. You can then do category.children category.children.parent childcategory.siblings etc, etc.

If you want to roll your own, it's one more line (of course, this doesn't give you all the fancy extra functions)

class Category < ActiveRecord::Base   belongs_to :parent, class_name => 'Category', foreign_key => 'parent_id'   has_many :sub_categories, class_name => 'Category', foreign_key => 'parent_id' end

Done... you can now do: category.sub_categories childcategory.parent childcategory.parent.sub_categories - self (returns siblings)

Amazing, eh?

That is very cool. I have a similar thing in the app I am working on now, I am going to give that a whirl. Thanks!

Hi, does the postgres-pr interface support SSL and if so is it set to support SSL by default or do I need to configure a ruby/rails document to activate it?