Thursday, April 2, 2009

Understanding Git Conceptually

As developers, we take for granted the use of a VCS. I started out with CVS then Subversion and since I work with Ruby on Rails, I have been introduced to git. Working in the Rails world, you cannot avoid git (and you really shouldn't try to!). Most plugins and gems for rails are hosted on GitHub and so basic understanding git is essential.

But only learning the basics of git is also a mistake you should avoid! When you're learning a new language and framework, you don't have much time (and motivation) left to learn in depth the in and outs of a new VCS. And so I have avoided really learning how git works and I only memorized the few commands I needed to commit, pull and merge.

A few weeks ago I stumbled on a great paper called understanding git conceptually. I was doubtful at first as to why I should understand the workings of git in order to better use it. I think the authors nails it right :
The conclusion I draw from this is that you can only really use Git if you understand how Git works. Merely memorizing which commands you should run at what times will work in the short run, but it’s only a matter of time before you get stuck or, worse, break something.
Reading the whole paper takes about half an hour and it helped me demistify things such as what is the difference between HEAD and head? What is a fast-forward merge? What is a commit object and how do you reference it? What is rebasing?

If you are working with git and understand don't yet understand the concepts behind it, take half an hour to learn something useful. It will save you some precious time in the long run!

Wednesday, November 5, 2008

Rails redirect_to :back

Here's a useful trick I didn't know about! The command redirect_to :back does just what it says, it redirects the user back to the previous action. This is similar to redirect_to(request.env["HTTP_REFERER"]).

The Rails documentation
states that this can be useful for forms that are triggered from multiple places.

In my case I needed it to redisplay the same page after a post that didn't validate. I could redirect the user back to the right action but some request parameters were missing in the post action that prevented this to work right.

For example, if the last request was /my_action?location=there, I would lose the location parameter if I didn't send it along in the post. And I didn't want to send the parameter along since I was calling a different controller which business logic didn't relate to these parameters.

Well, by using the HTTP referer, Rails redirects back to the URL with the right parameters and sends the user to the exact same location he was. Neat!

Thursday, October 16, 2008

Search in context with social networks

About two weeks ago I came across this interesting article by Miguel Carrasco about what Microsoft should do to beat Google at search. It basically states that the next big leap in search will be made by adding context to increase the relevance of search results. I highly recommand the reading.

Context is provided by social networks such as Facebook, MySpace, LinkedIn and others. By tapping in your social network, your search provider could know where you live, who your friends are, what are your interests and work field. These are all information that can be use to add relevance to search.

So for example, if my search provider knows I'm a tennis fan, searching for "US Open" should bring up results about the tennis competition and not the golfing one.

One annoyance I encounter on a daily basis is with Google Maps. I live in Montreal and I would say that about 95% of the queries I make are for addresses in Montreal. Shouldn't Google know this and default all my searches to Montreal? Most of the time Google just gives me irrelevant results if I only specify a street address. Hopefully, the map searching providers will take advantage of the latest innovations made in Firefox 3.1 on geolocation to provide better search results based on my current location.

The big fear when it comes to integration of social networks with search services is privacy. Quite frankly, with hundreds of "friends" on Facebook and LinkedIn, I already have restricted the information that I share on these sites to a minimum. And are my address, interests and work related infos really private information? To me, these are all information I'm ready to trade in favor of better search results.

Sunday, October 5, 2008

Developers, show me your feeds!

I have been wondering for some time now what other developers read when they are fresh out of bed with coffee in hand! If you're like me, you have this long list of technology feeds you track every day using your favorite feed reader to keep you updated on the latest news and best practices of your field. And god knows it evolves fast in our specific field!

So today I'm taking the lead and making my technology feeds on Netvibes public. You can have a look at :

http://www.netvibes.com/Modelix

I divided my readings in seven different categories :
  • Tech News
  • Tech Blogs
  • Tech Tips
  • Dev News
  • Ruby News
  • Ruby Blogs
  • Company Blogs
  • Comic (Mostly nerdy humor!)
My choice of news sources and bloggers is highly influenced by my location (Montreal) and my current interests (mostly Ruby and Rails).

Your turn now! Why don't you make your Google Reader or Netvibes feeds public and post it on your blog or in this comment section. Or at least, be a fan and let me know about your favorite bloggers and share it with other developers!

Friday, September 26, 2008

Alternate background colors with jQuery

I did a little javascript function with jQuery this morning to alternate DOM elements background colors . The function takes in parameters an array of jQuery elements and an array of hexadecimal colors and changes the background color of each element with the next color in the array.
// Alternates the background colors of the elements passed in parameters
// elems - Array of jQuery DOM objects
// colors - Array of hexadecimal colors
function alternateBgColor(elems, colors) {
elems.each( function(index){
var colorIndex = index % colors.length;
$(this).css('background-color', colors[colorIndex]);
});
}

It's only a three lines function but the cool thing about it is that you can alternate through as many colors as you need. I'm only using two for now but this could come useful at some point! I like how everything javascript just got easier with jQuery.

Tuesday, September 23, 2008

My first Rails application

I'm mostly done developing my first Rails application and I thought I could talk about my first impressions in this blog post. I assume I will most likely be preaching to the converted and so many good things have been said already about the magic of Rails so I don't plan adding much to it. I come from the Java world and I can only say the 60 hours development it took me developing this application in Rails (and I'm still a newbie) would have at least taken me twice the the time in Java. But enough with the greatness of Rails, I want to talk about the road bumps I encountered.

Some context

I did this application for a school that has a website showing schedules for over a hundred classes. Unfortunately, their server doesn't support any dynamic technology and this is all good old HTML. In order to update the content, they had to manually cut and paste from the Excel schedule file to the HTML files each new semester. Useless to say that this is time consuming and very error prone.

So I built a Rails web application for them where you can define your courses, classes and groups. The application automatically generates the static HTML files and then upload them to server through FTP. So it's like a CRUD with file reading and writing, downloading and uploading features.

First problem : Three levels of nested model mass assignment

This is something that gave me quite a headache. In my app, I have models called Classes, Courses and Groups. A class has many courses and a course has many groups. And furthermore, the order of the courses is important since it will change the display of the generated content.

I designed a single page to edit these nested models. It looks like this (it helps if you understand french!) :



It's basically a CRUD on steroids. Add, delete, edit, change the order of three levels of nested models in on page! I really liked this mass editing approach, I thought it was more productive for the user so I didn't want to change the whole layout just to fit some technological limitations.

Doing the first level was easy and straightforward. Coming to the second level, I fumbled a bit, did some googling and finally found this Railscast about complex forms. The screencast is out of date but the code displayed on the page (which was took from the book Advanced Rails Recipes) worked great for me.

The real challenge came when I was about to fit the third level of nesting. I didn't find anything on the Internet about it. I first tried naively to change the form inputs names so that it could be interpreted by Rails correctly and transformed into a hash. For example, the group price text input would be named :

class[course][][group][][price]


Now that didn't work at all. First, Rails doesn't have the context of which group belongs to which course. And second, it didn't seem as if Rails could handle both pairs of empty brackets. When editing an existing class, only the first one would get populated with appropriate ID.

The approach I took to solve the problem was to flatten the third level so that I had fields that looked like this :

class[course][][title]
class[group][][price]

Before submitting the form , I dynamically changed the names of the fields belonging to the group model to add an index number between the brackets. This way I could group them and associate them with the corresponding course. I did this with jQuery :

// Correct the names so it matches Rails way of handling array values
function correctFieldNamesBeforeSend() {
$('.course').each(function(index) {
$('.groupRow input', this).each(function() {
name = $(this).attr('name');
newName = name.replace(/\[groups\]\[\]/, '[groups][' + index + ']')
$(this).attr('name', newName);
});
})
}

And finally in my class model, I took the groups from the hash to put them in the course hash to which they belong.

def new_course_attributes=(course_attributes)
course_attributes.each do |attributes|
addGroups(attributes)
courses.build(attributes)
end
end

def existing_course_attributes=(course_attributes)
courses.reject(&:new_record?).each do |course|
attributes = course_attributes[course.id.to_s]
if attributes
addGroups(attributes)
course.attributes = attributes
else
courses.delete(course)
end
end
end

# Merges the groups attributes in the course attributes
def addGroups(attributes)
attributes.merge! groups[attributes[:position]] if attributes
end

This did the trick but it was fairly complicated to implement. I wish there was a more simple way!

Second problem : Form validation

This second problem is somehow related to the first and got me cursing at my computer. Since some of my fields in both the first and second level needs validation, I had to handle the error messages. And to add to the pain of this nested validation, my application is written in French which means I cannot use the basic default validation messages. Rails is not yet very good with I18N.

The basic validation messages all display the name of the model attribute in front of the message. I was stunned to realize there was no built-in way to change this behavior. I found the custom error message plugin that offered a solution and this blog post that offered another.

I finally opted for the second more manual solution and implemented an ErrorsHelper overriding the default error_message_for method. I also put some code in there to get rid of the annoying 'Course is invalid' error message occurring when there is a validation error in my nested model.

Although it worked in the end, it still felt like a big a hack and a lot trouble that could have been avoided. My code also ended up being not so DRY with repeating validation code like this :

validates_presence_of :title,      :message=>'Le champ Nom de l\'atelier est obligatoire.'
validates_presence_of :html_file, :message=>'Le champ Nom du fichier HTML est obligatoire.'
validates_presence_of :img_file, :message=>'Le champ Fichier de l\'image titre est obligatoire.'

The solution lies ahead

The good news is that the Rails core developers seem to be aware of those hassle and have plans to make this all easier in the coming release of Rails 2.2. I found this blog post by Ryan Daigle on automatic mass assignment. This should make my hack for the nested models irrelevant.

Rails 2.2 also promises a lot on the I18N side. I found this demo app that gives a taste of what is coming. That will probably help out localizing the validation messages.

Despite these two minor drawbacks that held me captive to my computer long through the night, my first Rails experience was very positive and I'm now considering completely dropping Java development in favor of Rails. I guess that will depend on what the market looks like for Rails developer at this time.

A special thanks to Mathieu who did a code review of my application on a sunny Saturday afternoon and gave me some very useful tips on Rails and Ruby. Starting out with a new technology always comes easier when you have passionate friends to help you!

Tuesday, September 16, 2008

Any Java freelancers out there?

Lately, I made the switch from making a living out of Java consulting to become a full-time freelancer. My motivations for doing so were, among others, mainly dictated by the need to :
  • Work more from home (no more grey cubicles and old 15 inches CRT monitors for me!)
  • Have a more flexible schedule (sometimes inspiration comes in the middle of the night)
  • Work on multiple projects at the same time
  • Take time to learn new technologies, participate in conferences and start a blog
So far I haven't been disappointed except for one thing : I can't seem to find much freelancing Java opportunities. Now, I'm just starting out as a freelancer and it is way to soon to draw any conclusion but I'm beginning to doubt. Is java freelancing possible?

Now don't get me wrong, there is a lot of java consulting opportunities. I still get a lot of phone calls for Java contracts but being on-site is always a non-negotiable requirement. From what I can see, PHP seems to be more suited for freelancing. It's the technology of choice for smaller web development companies and the bigger companies working with Java won't allow their code to get out of their walls or simply want to keep a closer eye on their contractors by making them work at the office.

I've always found PHP a little messy for serious development. I am now intensely learning Ruby on Rails in the hope that it might be easier to make a living freelancing with this technology (and also because it's a lot of fun!). But it's a long shot and I'm not sure where it's going to lead.

So how about the other freelancers out there? Any of you doing Java? Who are your clients and how do you find them? Are you allowed to work from home? Are you working in team or on your own?