It’s obviously been a while since I’ve posted, so I wanted to provide an updated. I’ve been inured with too many things that have distracted me from my Rails project for a time, though I hope to return to it soon as I hope it will be profitable for me in more ways than one. I’ve lately been playing with Grails, the need arising at work for a quick and simple blog-like tool to provide status updates via RSS to an existing Java web application.

This exercise has been interesting and helped me see the great similarities between Grails and Rails, as well as some differences. Truthfully I haven’t spent much time with Grails, so I don’t have much to report yet, except that Groovy is and since it compiles to Java bytecode that makes it a lot easier to use at existing Java shops than Rails. On the other hand, for side projects that will live on the Internet on commodity hardware, be it shared or private, Rails is a great framework.

One thing I will make note of in the hope that it will be useful to someone else, is that if you are working with Grails and wanting to deploy a WAR to some servlet container that only implements Servlet Specification 2.3 you can do the following:

grails -Dservlet.version=2.3 war

This requires, I think, at least version 1.0.1 of Grails. I did it with version 1.0.1 and 1.0.3. Of equal or more importance, though, is to set the app.servlet.version property in the application.properties file to 2.3, since that is the value that will actually be used when generating the web.xml for your application (where it really matters).

Unfortunately I ran into other problems (NoSuchMethodError on org.apache.tools.ant.ProjectHelper.getImportStack()) which I have yet to get around. I was deploying to WebLogic 8.1.6 and, so far as I know, the only version of ant in the classpath is the version deployed with the WAR, which is 1.7.0.

I hope to play around with Grails more, preferably on a real project that might start small and grow into something valuable to someone. And I somehow have to find time to get back to my Rails side project.

Have you ever wish you could tell Rails the name of the table that mapped to your model class?  Perhaps you want a model to represent a legacy table (which could be any table that already exists which is either too painful to recreate or over which you have no control).  Or perhaps you just want to be strange and call your class “This” and your table “that” (not something I’d recommend, but if you must satisfy that urge, you can).  Here’s how:

class Customer < ActiveRecord::Base
set_table_name "customp"
end

Now Rails will look for the table called “customp” when persisting or reading instances of Customer.  You can also use the more direct form:

class Customer < ActiveRecord::Base
self.table_name = "customp"
end

This tip comes from page 282 of the Rails book.

I got tired of seeing the deprecation warnings about the old Rails pagination helpers, so I decided to seek out a better approach, but of course I wasn’t going to implement it myself.  With all of the skilled Rails pros out there, I had every intent of leveraging someone’s else’s success.

I succeeded, thanks to Ilya Grigorik and Alex Wolfe.  Ilya wrote “Faster Pagination in Rails” which leverages Alex’ paginating_find plugin to provide limited result sets at the database level.  Ilya’s post includes code he wrote to provide a neat and tidy presentation of the pagination links.

It only took me a few hours to get it working.  It should not have taken this long, but I’m notorious for making things harder than they need to be.  In this case, after I grabbed the code from Ilya’s post and installed the paginating_find plugin for my application, I modified my view to use Ilya’s helper.  This is where it all went wrong.  I was about to do something like this

<%= render :partial => ‘shared/pagination’ %>

but instead did this

<%= windowed_pagination_links(@results) %>

As it turns out neither one of these is correct, but the second one is even more incorrect than the first and led me down a bad path for a couple hours (just what every developer hates).  Since I don’t ever want to repeat that mistake again, and perhaps someone else out there is having this same trouble, I’m writing about it.

What I saw in my functional tests after modifying my view as above (and the associated controller) was

ActionView::TemplateError: undefined method `page’ for #
On line #22 of app/views/sell/list.rhtml

This frustrated me for hours because I couldn’t figure out why it didn’t recognize the page method.  I checked the code, double-checked Ilya’s blog (and many comments) and checked my code to confirm that I was specifying the :page option to the find method.  Sure enough.  Here’s what my controller had

@stuff = Listing.find_by_all_user(session[:user_id],
:page => {:size => 10, :current => params[:page]})

Now if you know about paginating_find, you may notice a problem with the code above.  But since paginating_find was brand new to me, I didn’t notice it.  I’ll explain the problem here shortly.  First let me explain the problem with my view.

What I really needed to have is

<%= render(:partial => ‘shared/paginate’, :locals => {:collection => @stuff}) -%>

So it turns out that I started out on the right path, but left off a critical piece, which is the passing of the controller-returned collection @stuff to the partial so it can do it’s rendering.  If I had even once executed the code using this render(:partial) approach, I’d have been at least on the right path.

Once I got this figured out, I still had problems.  My controller test was still failing with an error like this

ActionView::TemplateError: undefined method `page_count’ for #
On line #2 of app/views/shared/_paginate.rhtml

I returned to Ilya’s blog and read more comments, re-reviewed the entry itself and didn’t see what I was doing wrong.  Then I looked more closely and noticed that all of the references to the use of the paginating_find plugin were using the find() method of any given model.  So I thought perhaps it’s called paginating_find for a reason, that being that it works only with the find() method, not with the Rails dynamic methods find_by_XXX and find_all_by_XXX.  But I was using find_all_by_user (where user is the property of my model that I wanted to find stuff by.

So a quick update to my code fixed the problem and all tests are passing.

@stuff = Stuff.find(:all, :conditions => ['user=?', session[:user_id]],
:page => {:size => results_per_page, :current => params[:page], :first => 1})

Now I’m a happy camper on the Rails.

I need to be able to assert that a response from a Rails controller doesn’t contain certain content, for example when the same action will respond to both GET and POST methods.  In my case I’m writing a register method in a LoginController and I want it to render the same view, but if the registration was successful I do not want the registration form to be displayed again and instead want some text that answers the question, “Ok, I’ve registered, what next?”

Turns out this is easy (I should have known).  I found the answer on this Cheat Sheet.  The assert_select test helper accepts an equality? parameter, so give it false and it ensures that the content does not contain the value specified in the selector parameter.

I recently resumed work on a Rails project I started a few months ago only to find that some of the functional tests that Rails generated for some scaffolding code were failing. These tests were failing on a fresh checkout from Subversion, so it was obvious that I’d neglected to run the functional tests before at least my last checking a few months prior. That of course was a problem, but now I’ve corrected that by figuring out a better way to ensure that I can always run the tests.

I spent all day yesterday working on functionality other than the one controller that was failing. I saw the failing tests but decided that since they were on controller code that was generated by scaffolding, I would let them go. I actually thought perhaps the tests were generated wrong, but of course that was not the case. Since I’m now using autotest, I decided I’d better figure out why those tests were failing because I just couldn’t bare to see those failures flashing before me all day while I’m working (and I didn’t want my little project to suffer from the Broken Window theory).

I started by looking at the failures, of which there were four (the real controller name has been changed to protect the innocent).

1) Failure:
test_create(SomeControllerTest)
[/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:26:in `assert_response'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:18:in `assert_response'
test/functional/some_controller_test.rb:59:in `test_create']:
response to be a <:redirect>, but was <200>

2) Failure:
test_edit(SomeControllerTest) [test/functional/some_controller_test.rb:72]:
is not true.

3) Failure:
test_show(SomeControllerTest) [test/functional/some_controller_test.rb:40]:
is not true.

4) Failure:
test_update(SomeControllerTest)
[/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:26:in `assert_response'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:18:in `assert_response'
test/functional/some_controller_test.rb:77:in `test_update']:
response to be a <:redirect>, but was <200>

4 tests, 10 assertions, 4 failures, 0 errors

So I started by looking at the test for Failure 1 to see if there was anything odd going on. I noticed that the test was trying to create the model without any of its properties. So I went to the code and sure enough, if a save was successful it was redirecting and if not it would render the new action. Since no properties of the model were being passed to the controller, no model was being created. A quick modification to the test to pass in the required properties and it was passing.

At first I hard-coded these properties into the test, but then I took at look at the fixtures and decided I should be using those. It was a good thing I did, too, because it turns out the remainder of the tests were failing due to bad fixture data. The first two fixture entries were missing some properties that, after the original creation of the model, were added as required properties. So I added the missing properties and, to my pleasant surprise, the rest of the failing tests passed.

So the moral is: keep your fixtures updated as you modify your model, especially if adding required properties. AND, more importantly, always run your tests and you’ll know right away as soon as you break something (at which time it will be much easier to figure out what caused it).

The JAD Java Decompiler is a handy tool for Java developers, both for academic use and for recovering your own code on those (hopefully) rare occasions when you lose the source but have the .class files.

I used to use JAD via the Jadclipse plugin for Eclipse in Windows. I switched to Ubuntu a few months ago (and have never looked back). I tried to use Jadclipse, but ran into library problems in Ubuntu. Here is the message I got when running jad from the command line.

jad: error while loading shared libraries: libstdc++-libc6.2-2.so.3: cannot open shared object file: No such file or directory

I finally found the solution on the Ubuntu forums, and in case it should ever get lost or removed, I wanted to make note of it here.

sudo apt-get install libstdc++2.10-glibc2.2

That command will install the missing libraries and jad (both from the command line and Jadclipse) will work like a charm.

I’m in the early stages of starting a new web application project for public use.  I’m currently trying to determine what language I want to use for the application.  Initially I considered Java, since I am a Java developer by profession.  But for the same reason I may choose not to use it. ;)   Then I considered Ruby since I’ve heard and read a lot about it and know some people who are using it on paid projects currently.  Ruby on Rails provides some benefits for web applications.  While looking into Ruby I came across Django (which is written in Python).

Now I’m considering using either Ruby (and Rails) or Python (and Django).  But the jury is out still.  Here are some links of interest.

I wish I’d decided already so I could start coding. ;)

I recently bought a Mac Mini because I’ve wanted a Mac ever since Apple released Mac OS X and I’ve wanted one even more ever since they moved to the Intel platform. The Mini is an inexpensive way to get a Mac so I finally took the plunge (the $100 rebate from Micro Center certainly helped).

I absolutely love the Mini and if I had my way I’d use it all the time, at work and at home. One thing I’d love to be able to do, especially at work, is use dual monitors with my Mini. Unfortunately, the Mini has only a single DVI video port, so without a special hardware accessory I cannot use dual monitors with my Mini.

However, while searching for a solution, I came across Synergy, an open source client/server application that enables computers with different operating systems to share a keyboard and a mouse and even the clipboard. It works across Windows, OS X and *nix operating systems.

So tonight I followed directions I read on the Lifehacker site and in under one hour I was using the keyboard and mouse of my Vaio laptop on my Mac Mini! I could move the house cursor from my PC right over to the Mac, at which point the keyboard on my laptop was redirected to the Mac as well.  This happened as seamlessly as when using a typical single-PC setup with dual monitors.  I couldn’t believe it.  I could even copy and paste text from the Mac to the PC and vice-versa!

That was pretty cool, but at home it’s not terribly useful for me — I’d much rather use the keyboard and mouse attached to my Mini to do things on my Vaio laptop since that would enable me to sit straight at my desk. So I reconfigured it to make the Mini the server and the PC the client and it works beautifully! The only thing I had to do was use the IP of the Mini rather than the hostname when configuring the Windows machine to connect to the Mac Synergy server.

This is an absolutely fantastic way to use both a Mac and a PC at the same time in cases where that is, for whatever reason, either desired or necessary.

References:

http://lifehacker.com/software/productivity/how-to-turn-your-dualmonitor-pc-into-a-dual-macpc-system-106123.php
http://lifehacker.com/photogallery/set-up-synergy-on-mac/1760558
http://lifehacker.com/software//hack-attack-control-multiple-computers-with-one-keyboard-and-mouse-254648.php#synergy-client

The Yahoo! User Interface Library (YUI) is a robust set of JavaScript controls and utilities for building interactive web applications. The library is released under the BSD license so it is free for use in all kinds of applications. Some of the available utilities include drag and drop, eventing, animation and a connection manager. The library controls include auto-complete, calendar, container, menu, slider, tree view and tab view.

Aptana is “The Web IDE,” a “robust JavaScript-focused IDE for building dynamic web applications.” It provides full code-assist and JavaScript debugging. It ships (that is, electronically) with some of the YUI libraries so you can quickly create projects leveraging YUI to try them on for size. Aptana is supported on Windows, Mac, Linux, and as an Eclipse plug-in (and thus virtually any modern platform).

I haven’t yet had the pleasure of using either of these tools but now that I know about them I hope to have the pleasure soon. If you’ve used them, tell me what you think.