Archive for the ‘Programming’ Category

Fatten Up Those Error Pages For Internet Explorer 6.0

Posted on December 5th, 2008 in Programming, Web Development, tips | View Comments

One of the not-so-joyous moments of being a web developer is the fact that we still need to support browsers that are ancient (by technological standards). Specifically, I’m talking about Internet Explorer 6.0. A quick look at the site statistics of one of the major websites I’m currently working on says that 16.9% of users visited our site using Internet Explorer 6.0. That’s obviously not the majority – Internet Explorer 7.0 takes that honor with 38.4%, followed by Firefox 3.0 with 19.8%. But it’s still a large enough number for the higher-ups to decide not to ignore it.

Since I never, ever use Internet Explorer 6.0 for any regular browsing (and you shouldn’t, either – read why on sites like Browse Happy), this past week I decided to give the site a test run with Internet Explorer 6.0 (using IEs 4 Linux). Besides the frustration of finding some incompatibilities with standard CSS on this browser, everything else seemed to work well. I then triggered an error on purpose, just to make sure our error handling would be handled properly (display our custom 404 error page instead of a nasty -yet customized – 500 error page). To my surprise, Internet Explorer 6.0 decided to render its own friendly error page instead of our custom one.

Thinking one of my colleagues removed it for whatever reason, I fired up Firefox and triggered the same error. The custom 404 page appeared correctly. Heading over to a Windows laptop, I had the custom error page on all browsers, including Internet Explorer 7.0. This left me scratching my head for a while. Although I’m already used to Internet Explorer 6.0 to act in different ways, standards be damned, this act seemed to be stupefying.

I was about to give up, thinking that Internet Explorer 6.0 used to hijack everyone’s custom error page just to hawk their own, I did a search on 404 error pages. Lo and behold, Wikipedia came through with a response that I would have never guessed:

Internet Explorer (before Internet Explorer 7), however, will not display custom pages unless they are larger than 512 bytes, opting to instead display a “friendly” error page.

Wow. Who knew that size mattered? On a custom error page, of course.

Our custom 404 was basically just a regular HTML with the standard tags, and one image and it weighed less than 300 bytes. I couldn’t modify the design or anything, so I just padded the error page with a long, boring and senseless comment, explaining why said comment was there. After ‘fattening up’ the file to more than 512 bytes, the error page started appearing on Internet Explorer 6.0.

It turns out that older versions of Internet Explorer had a threshold value in the registry which decided whether to display their own error page or a custom one. Why? I have no idea. Thankfully that was fixed for recent versions. But for all of the unlucky ones who still have to support ancient technology, this is another special Internet Explorer 6.0 quirk that needs to be taken into consideration.

For more information, including the default size limitations for other error pages, read this site (aptly named ’404-error-pages.com’) has all the information you need.

Want To Learn About Rails 2.2? Get The Envycast and PDF

Posted on November 2nd, 2008 in Programming, Reviews, Ruby On Rails | View Comments

A couple of weeks ago, I wrote a short post about the first Envycast released by the guys over at Rails Envy. I really enjoyed their first foray in the world of screencasting, so I was looking forward to see what else they would offer us in the future.

With the imminent release of Rails 2.2 (Release Candidate 1 was announced last week), it makes complete sense that the new Envycast would focus on Rails 2.2. In the Ruby on Rails 2.2 Screencast, Gregg Pollack and Jason Seifer talk about all the goodies that have been included in Rails for our use. Even if you’re currently subscribed to Ryan Daigle’s blog and follow the Rails commit history, it’s still nice to have everything in one easily accessible place. While an Envycast in itself should be awesome, they decided to also have a PDF available, detailing all of these changes.

Screencast

Clocking in at 44 minutes, this screencast takes you through the changes in Rails, divided by component (ActiveRecord, ActiveSupport, ActionPack, ActionController, Railties) and specific topics (Internationalization and Performance). Like the first Envycast, all the action (well, as much ‘action’ as you can get in a Rails screencast) is done in front of a green screen, with either Gregg or Jason explaining what’s on the screen. As I mentioned previously, this gives the screencast a nice, personal feel, making the learning (and retaining the information) experience enjoyable and much easier – at least to me – than other screencasts. The infused humor also helps a lot with the learning process, making you feel comfortable and in a relaxed setting, which is key for learning new stuff.

Considering all the changes that have occurred in the six months between Rails 2.1 and Rails 2.2, this screencast does a good job in explaining all the new stuff. Although it doesn’t go too much into detail with some new features (thankfully so – I prefer short and simple, just like my Ruby and my Rails), my major gripe with this screencast is the lack of more detailed explanation on one major feature I (and I’m sure hordes of other Rails developers) was looking forward to: Internationalization. While I do understand this would need sufficient time to explain this new feature properly, I thought this was too big of a feature to just briefly touch on. They do encourage viewers who want to learn more to download and play with the Internationalization Demo App that was created just for this purpose.

Besides that, Gregg and Jason do an awesome job with this screencast. They explain these new features really well, make good use of the green screen (well, besides dodging pigeons and running away from Godzilla – trust me, you’ll see when you get this screencast) There were many “Whoa, I’m so going to use that in my next project!” moments for me, which for some reason didn’t happen when I read about these changes in Ryan Daigle’s blog.

After my short review of the first Envycast and liking it a lot, I was anxious to see if the Rails Envy crew would continue along these lines. I’m glad to see that they still produced a great screencast that’s easy to learn from and fun to watch.

PDF

Like I mentioned, they not only released a screencast on Rails 2.2, they also released a PDF to complement the screencast. The Ruby on Rails 2.2 PDF was written by Carlos Brando, a Portuguese Rails Core contributor who also wrote a similar (and excellent) e-book on Rails 2.1.

While the screencast goes over the new features in Rails 2.2 briefly, the PDF goes more into detail, with explanations and code examples throughout the book. There’s even an entire chapter on Internationalization, compensating for the lack of explanation in the screencast. At 118 pages (of which 86 are in-depth explanations of the Rails 2.2 features, 9 pages detailing the bug fixes in this release and 14 pages of the entire changelogs by component), it gives you all the new details in Rails 2.2, perhaps much more than what you need.

While the content is rock-solid, the formatting of the guide wasn’t too much to my liking. The PDF is in landscape orientation, which usually isn’t a big deal for me. However, the author didn’t seem to take advantage of this fact, as I think it could’ve been printed in portrait orientation without much formatting changes. Also, the PDF is just straight text (well, not counting the cover page, for those who like to nit-pick). There are no diagrams or anything similar – just explanations and code samples. Some diagrams or other illustrations wouldn’t have hurt to be included.

As a matter of example, if you see any of the Peepcode PDF’s (like the one on Unobtrusive Prototype.js), you’ll see they took advantage of the page sizes, filling it up without making the pages feel too loaded. These make reading less boring, while still keeping the core information there. It’s a nice combination.

Aside from some very minor gripes, these are quality products that will further your knowledge of everything Rails. I definitely recommend them to any Rails developer who is interested in keeping up to date with the rapidly-changing Rails world. Kudos to the Rails Envy crew for putting up another great product. I’ll be looking forward with what they come up next.

Difference between validates_presence_of and validates_length_of

Posted on October 22nd, 2008 in Programming, Ruby On Rails, tips | View Comments

Today I had a pretty frustrating moment. I made some new changes in the morning, which included the addition of a new column in the database. This field wasn’t required, but I needed to limit the amount of characters a user could enter in that string. So I did the proper thing and set this in my model:

validates_length_of :locations, :maximum => 200

I did a quick test, and the validations worked great. So I promptly committed the code to our repository. A few minutes later, our Continuous Integration system sent me a nasty E-Mail: I broke the build.

I frantically searched the errors in the test, and it seemed that the tests were expecting that field I just added to have something. I was stumped, thinking that unless you specify validates_presence_of, set a range of characters in the validates_length_of or perhaps some regular expression validations in the model, that would be the only time a model would require the field to be there. I hadn’t done any of these.

Frustrated, I added a simple string to the fixtures and the test code for this field, and the tests passed. Not content in just making something work, I needed to know what was up. So I started digging around, and found something that now seems obvious, but I totally ignored before.

Whenever you submit a form for a model in Rails to insert a new record in an ActiveRecord model, all the fields you have set in the view are passed in the POST request. However, if you didn’t enter anything in a field, the parameters for that field would simply be sent blank. In this case, validates_length_of doesn’t bitch about the missing field, because it’s there. As long as the number of characters – in this case, zero – isn’t more than what I specified in the model, it’s all good. However, the tests were failing because since I hadn’t specified that new field in the fixtures, the parameters were sending that field as nil, which caused the previously mentioned validation to scream out.

So just as a quick review:

  • validates_length_of – Verifies if the field is within the amount of characters specified in the validation code. If no minimum is set, it won’t mind blank fields, but it will mind nil fields.
  • validates_presence_of – Verifies if the field is nil or blank.

Like I said, it’s obvious now, but not so much when I was getting alerts that the build failed for some silly reason.

Quick and Dirty Browser Cookie Testing

Posted on September 30th, 2008 in Programming, Ruby On Rails, Web Development | View Comments

On a recent Rails project, I was asked to verify if the visiting user’s browser has cookies enabled, and display a message on top of the screen if they don’t. While I don’t want to get into the reasoning why, or get into a flame war whether the site should still be accessible regardless if the user’s browser has cookies, I still needed to implement it.

Since it’s a Rails project, I thought of checking if the session cookie that Rails sets in the Application controller was set. But Rails sets the session after the view is rendered the first time (I have a more detailed explanation somewhere but don’t have it with me, so maybe next time). This means the first time the user visits the site, it will incorrectly display the warning message. Subsequent views will test correctly, but this obviously won’t work.

So I decided to implement a redirect, thanks to ideas given by this blog post. It worked, but it left me with a parameter in my URL the first time the user visited the site. It didn’t seem clean, and the higher-ups didn’t like it either, so off it went.

Then I was given the idea to check it via JavaScript, and with some slight tinkering I think I got what I wanted:


Basically this uses JavaScript to set the cookie when the page is rendering and immediately checks for its availability using a regular expression. If it’s found, then the user has cookies enabled and we can safely delete the test cookie (provided the user has their system clock set after January 1, 2001). If the cookie isn’t set, that means the user doesn’t have cookies enabled in their browser, so we display the ‘cookies_disabled’ element with our message inside.

This function is called in our application layout, between the <head> tags, meaning it’s called for every single page that renders the default layout. I haven’t observed any type of performance issue this might have, but I might have missed something along the way. And there’s probably a better, more efficient way to handle this as well, so if you have any suggestions, feel free to dtop a comment and let me know.

That’s Why There Are Choices, People

Posted on September 18th, 2008 in Opinion, Programming | View Comments

I was having a quick tech discussion the other day on a non-tech message board I visit on a daily basis. I had mentioned how frustrating it is to have to spend hours developing for good ol’ obsolete Internet Explorer 6.0, and why people are so damn lazy to upgrade. There are countless reasons why people don’t upgrade, which I won’t go into now to avoid a long, long rant on why I think these people should be stripped from their computing privileges. But I was talking about the recent developments in web browsers, in particular how Firefox 3.1 is going to be much faster, or how Internet Explorer 8.0 is promising to play better with web standards, I received this delightful comment from one of the few techies (and one of the few females) in that forum:

He can shove Firefox 3 where the sun doesn’t shine, and if he suggests Internet Explorer 8 in person I will be forced to cram his balls up over his head whilst they are still attached to him.

Just lovely. And I hadn’t even suggested that people upgrade!

The particular reasons she gave me as to why she made this statement are irrelevant to the discussion (“Firefox 3 doesn’t support all my add-ons yet and Internet Explorer lost me a long, long time ago.”), but something slightly ticked me off about this brash statement.

Every single person on this planet has an opinion to express, for whatever reason. People involved in computers aren’t excluded. I’d say we absolutely love expressing our opinions about a myriad of things, leading to sometimes heated (and entertaining) discussions: Windows vs. Linux vs. Mac, Ruby vs. Python, vi vs. emacs… No matter what you say, there will always be someone to express the opposite.

I learned a long time ago to avoid these discussions altogether. Why? It’s not because I’m a poor debater and fear I’m going to lose (which is most likely true). It’s because no one in this world will ever be pleased. That’s why there are choices in this world. To put it as simple as possible, someone wasn’t content with something, so they made another thing. And they’re happy with it.

So if I’m happy with Ruby and Rails, and you’re extremely happy with Python and Django, then I respect your opinion, sir. Just don’t come down on me and run down a zillion reasons why Ruby or Rails suck (which are probably variants of “Rails Can’t Scale“). Be happy with what you have, I’ll be happy with what I have, and we can co-exist nicely in this vast software development universe.

Envy Casts – The New Hotness?

Posted on September 16th, 2008 in Opinion, Programming, Ruby On Rails | View Comments

Last night I was in the mood to just review some of the stuff I already work with on a daily basis. I’ve been reading up on a lot of new stuff that I’m dying to play with, so a quick review of familiar concepts would be a welcome change of pace. Plus, it always seems I’m learning new stuff whenever I go back to an old concept. So I was searching around to see what I could get. I’ve already exhausted most of my Ruby and Rails books, gotten most of what interests me on PeepCode, and seen virtually every single episode of Railscasts, so I wanted to see something different.

That’s when I remembered that the guys from Rails Envy started producing their own screencasts, originally dubbed Envy Casts. As you can see with what I wrote above, and what I’ve written previously, I absolutely love screencasts. And since I’m an avid listener of the Rails Envy Podcast, I thought I would give these guys a try.

So after viewing the screencast on my way to work today, I have to say that Gregg Pollack and Jason Seifer have a good thing in their hands. Their screencasts are totally different from everyone else’s, which is immediately apparent. Instead of just a voiceover of how something is done, they actually have the guys (mostly Gregg) in front of a green screen. While it would virtually be the same if they went the regular screencast route, this adds some sort of personal touch.

Of course, the guys inject their humor as usual (with Jason usually appearing on screen for comedic purposes and nothing else). It even has quick educational breaks, with Gregg posing as a doctor to give us lessons on how our brains work. It has absolutely nothing to do with Ruby, Rails, Active Record, or anything related to software development, but as I mentioned, it provides quick breaks between topics.

So far, they only have one screencast covering Active Record. But I’m definitely looking forward to subsequent screencasts, as long as they’re as good as this first one. Perhaps we have the new hotness of the screencast world in our grasp.

Hoptoad – Rails Exception Catching Made Easy

Posted on August 27th, 2008 in Programming, Ruby On Rails, Services | View Comments

Have you ever installed the Exception Notification plugin in one of your Rails apps, just to get bombarded with E-Mails of the same error over and over again? It’s happened to the best of us.

Thankfully, people in the Rails community have been working on different solutions to handle this. One I discovered recently, which I’m really loving a lot, is Hoptoad, brought to you by the awesome people over at thoughtbot. Really, how can you not be an awesome group when your blog is titled Giant Robots Smashing Into Other Giant Robots?

Anyway, Hoptoad is a service which captures all exceptions that occur in your Rails application, and aggregates them into one place. This way, if you have, for example, a link to AJAX functionality that causes a 500 error, you’ll only get one E-Mail notifying you about the error. The service will actually log the times it’s happened, though. It also provides a full stack trace, session information, parameters that were passed, and just about everything else you need to make a full assessment on why your application failed. Oh, and one more important thing: it’s totally free. Can’t beat the price.

It’s as simple as creating a new account and setting up a project, installing their plugin on your application, putting the assigned API key in an initializer file, and that’s it! It took me about 2 minutes to set everything up the first time. The interface is pretty straight-forward. When you first log in, it will show if any of your projects has any errors (which any developer can mark as ‘Resolved’ so it won’t show again). If there are (and face it, we all get errors at one point or another), then as I mentioned previously, you can view the stack trace to see what happened. Nice, simple and helpful.

I’ve noticed there are some other sites that offer these services (like Exceptional), but none that seem to have the simplicity of Hoptoad. Not that I think the other services are bad, but it’s just not what I want at this moment. In my particular case, I really don’t need to have an app that integrates with other services, let’s me leave comments about an error, or see how many times in the past week the error occurred. I just want to know if my app is getting errors. Hoptoad does just that.

I fully recommend Hoptoad for any Rails app. If you don’t have any sort of exception notifier in your app, you should get something now. If you do, then I hope you never have to constantly use it!

That Was Easy – Upgrading From Rails 1.2 to Rails 2.0

Posted on July 31st, 2008 in Programming, Ruby, Ruby On Rails | View Comments

It’s been an interesting week for me. I got a first-hand taste on upgrading a Rails 1.2.x application to Rails 2.0. To be honest, I was terrified when this task was presented upon me. I had never done this before, since virtually all the Rails 2.0 (and 2.1) apps I’ve worked with have started with that particular version, not an upgrade. Seeing that the application in question had been under development for a long time (hence still using Rails 1.2), I immediately though that an upgrade to Rails 2.0 would cause the app to break so bad, I would be having “NoMethodError” messages in my nightmares for a long time to time.

So with the thought of a long week of fixing trivial changes to make the application work correctly once again, I removed the frozen Rails 1.2 directory from the application and froze Rails 2.0 in its place. I started Mongrel, and… It worked. Like it really worked. Well, not 100%, but most of the application worked as it was before! I definitely couldn’t believe it. That was probably the easiest framework upgrade I’ve done in my entire life. Most of it had to do because of me doing a lot of refactoring for code that I had knew would be removed from the framework soon, but also kudos to the Rails Core team for making this pretty straightforward.

Like I said, it didn’t go 100% smoothly, so I thought I’d share some of the gotchas I encountered during the upgrade.

‘extract_options_from_args!’ method

The extract_options_from_args! method was apparently removed in Rails 2.0. Upon further inspection, there were many plugins using this method, but only one (nested_has_many_though) wasn’t properly handling it. All I had to do was update that particular plugin, and the error disappeared from the entire application. So my recommendation is to upgrade any currently existing plugins you have, although this is more tricky if you have old plugins that aren’t being currently maintained.

‘You are being redirected’ problem

In some places of the application, when an action used ‘redirect_to’ to send me somewhere else, a page would appear, simply saying ‘You are being redirected‘, with a link to where the app should’ve been redirected. The problem: there was a parameter named ‘status’ that was used for the redirect. Changing the parameter name to ‘state’ solved the problem. I’m guessing it’s because Rails uses the word ‘status’ to set the HTTP code for a redirect, so it caused this hiccup.

‘Called id for nil’ error

I was also getting errors for nil variables where they didn’t exist before. The problem here was caused because some ‘form_for’ tags were using variables that weren’t initialized previously in the controller. Taking for example the following code: <% form_for @item, :url =>items_path do |f| %>. The instance variable ‘@item’ wasn’t declared in the controller (or the view, although if someone did that, I would hunt them down), yet in Rails 1.2 it would work properly. It was just a matter of adding @item = Item.new in the controller for the action, and it would work fine again. I guess this was just done to make sure things are coded correctly, which I really don’t mind.

Route Globbing and escaped slashes in URL

This one was an interesting one. Part of the application uses route globbing, where you can set a route to grab everything in a URL and set an array. The application in question was using this in one part of the application, to get a collection of IDs and process them for some other functionality. However, this was being done via a link generated using ‘link_to’, which promptly went to escape the slashes between the IDs (from ‘/’ to ‘%2F’, which the browser read well, but Rails 2.0 apparently doesn’t like), and the route globbing wouldn’t return the array as expected. For example, previously in Rails 1.2, if the URL ended like items/process/101/105/110, the route globbing would return an array of three elements: ["101", "105", "110"], which is what the app expected. In Rails 2.0, since the slashes were escaped thanks to ‘link_to’, it would return an array of one single element: ["101/105/110"]. This problem was already reported and seems like it’ll be fixed in Rails 2.1.1. But in the meantime I did a quick fix: take the element in the array and split it using Ruby’s split method to create the array as it should be before processing.

Besides these errors, the rest went smoothly. The app has been running for two days under moderate testing, and nothing else appears to be broken. So it all went well. Hope this post helps someone get through some problem upgrading their old, creaky Rails app.

Fix my mistakes. Just don’t do it yourself.

Posted on April 3rd, 2008 in Programming | View Comments

When I arrived at my current job, most of the functionality from the Rails application I’m working on was already done by developers before me. There were still some loose ends to tighten, but almost everything was ‘working’. I say ‘working’ in between single quotes, because while the application was certainly working, it really only worked if everything was done in a seemingly exact pattern. Do something different from the pattern, and something will break. Like “Click here and fill in this, in this exact order, and put your cursor there, or the app will give an error.

I understand why this was done this way. I usually code this way too: after deciding what I’m going to do, I whip up a very crude version of what I want to do, then I take care of some loose ends that could be made better. But there are some things I do along the way to avoid having too many loose ends when I finish writing my basic functionality.

Most of us have heard the phrase “premature optimization is the root of all evil” by Donald Knuth. While this is true, I believe that we should think from the beginning about optimization before writing code. Your algorithm or pseudocode should be as optimized as possible from the start to avoid these things. If you think through your problem well enough, too much optimization won’t be needed.

With web development and frameworks such as Ruby On Rails, it’s easy to forget these things. A lot of the times people just sit in front of their computers and code away, hacking up whatever’s on their mind without thinking it through. I admit I’ve been guilty of this behavior before. But with age comes experience, and I’ve learned a lot since then.

Anyway, back to my current code. Apparently the developers working on it before just sat down and wrote a lot of code without thinking about such basic things, like error-handling. It’s not like they didn’t have time to do it. My workplace isn’t a stressful place, my bosses are way nice, and while we do have deadlines, it’s not like we have someone on our backs constantly nagging that we have impending deadlines. Since those original developers don’t work here anymore, I can’t ask them why they coded like this, so I have to just deal with it the best that I can.

I created a document in our company’s Wiki with some coding tips that came off the top of my mind, so that hopefully any new hires can read it and follow them. Even if they know these things, it should serve as a reminder to follow these basic guidelines. By no means it’s a complete document, but these are the most common mistakes I’ve encountered.


Always handle errors gracefully

Try to never show the user an error page. If something went wrong, show a message letting the user know what went wrong, preferibly a `flash[:notice]` or `flash[:error]` message, which will appear at the top of the page, and send them somewhere where they can either try again or get more information.

Bad Example (If the item for some reason doesn’t exist, or a curious user changes the ID in the URL, it will show an not-so-helpful error page):

def offer_for_want
  @have_item = HaveItem.find(params[:id])
end

Good Example:

def offer_for_want
  begin
    @have_item = HaveItem.find(params[:id])
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "Some error"
    redirect_to :somewhere
  end
end

Use descriptive variables

Although using shorter variables keeps the functionality the same as using longer variable names, using descriptive variable names and conventions will help other developers understand how an action or function works more easily. Also, using normal Ruby and Rails variable naming conventions helps others get up to speed on the scope of the variable.

Bad Example (Notice the use of two- and three-letter variables, which are not descriptive to a developer who’s just working on this portion of the code):

def update_relationship(hi, wi, opt, modify_opt = nil)
  _have_want = {}
  _have_want['HaveId'] = hi
  _have_want['WantId'] = wi
  _have_want['Delete_add'] = opt
  [...]
end

Good Example:

def update_relationship(have_item, want_item, update_type, modify_option = nil)
  have_want_hash = {}
  have_want_hash['HaveId'] = have_item
  have_want_hash['WantId'] = want_item
  have_want_hash['Delete_add'] = update_type
  [...]
end

Comment your code!

All controller actions and model functions should be commented before the action or function, giving a brief description on how it works. Also, if the code is not self-explanatory or is done in a non-conventional way, a brief explanation should be included as well to let other developers know why the code was written that way, or how it works. This will also be useful for generating code documentation with RDoc

Bad Example (No comments anywhere):

def rate( _user )
  @current_user = _user

  transaction do
    user_tv = view_for(_user)
    user_tv.next_step = View::CF[:next_step][:nothing]
    user_tv.status_for_user = View::CF[:status_for_user][:nothing]
    user_tv.rated = true
    user_tv.save!
    self.rate!
    self.reload
    return ended?
  end
end

Good Example:

# Action to rate a user after an action has been accepted, completed and shipped.
# Only the people involved in the action are permitted to rate each other.
def rate(_user)
  @current_user = _user
  # Reloading the object attributes from the database, in case something was changed during the rating process.
  self.reload

  transaction do
    user_tv = view_for(_user)
    # Sets the next step of the action to 'nothing' for both users involved,
    # indicating that the entire process is complete.
    user_tv.next_step = View::CF[:next_step][:nothing]
    user_tv.status_for_user = View::CF[:status_for_user][:nothing]
    # Set a flag to mark the user's action as rated, so that multiple feedback can't be given
    user_tv.rated = true
    user_tv.save!
    self.rate!
    self.reload
    return ended?
  end
end

Properly substitute variables from MySQL queries for security purposes

Any query to the database where the user can enter the parameters (for example, a user enters terms in a search field) can potentially allow a malicious user to run a harmful query against the database, like dropping tables. These user-entered parameters need to be protected from these types of problems.

Bad Example (In this example, a user can enter something like ; DROP TABLE users as their search parameters, deleting the users table):

@item = HaveItem.find(:all, :conditions => "title = #{params[:search]}")

Good Examples (All of these samples do the same thing, except Rails sanitizes the parameters to make sure no arbitrary SQL code is run):

@item = HaveItem.find_by_title(params[:search])
@item = HaveItem.find(:all, :conditions => [:title => params[:search]])
@item = HaveItem.find(:all, :conditions => ["title = ?", params[:search]])

Sanitize any user input before rendering it in the view

Anything the user enters should be treated as potentially hazardous. Any unsanitized output can be vulnerable to Cross-Site Scripting. Any fields in the view that show information entered by a user should be sanitized. It's as simple as adding the h function before the string.

Bad Example (Anything the user enters in the database, when shown later in a view, can execute arbitrary code):

<%= @item.description %>

Good Example:

<%= h @item.description %>

Keep presentation and business logic separate

Thanks to the MVC paradigm, Rails makes it easy for any new developer to get find presentation code or business logic, but only if they're stored in the correct places. Any business logic (such as declaring variables, conditionals, etc.) should be kept in the controller or model and not inside the views. Likewise, all presentation code (such as rendering page updates via AJAX) should be done in either regular view files or RJS templates, not in the controller.

Bad Example (Variables being declared inside the view):

<% result ||= match_result %>
<% size ||= :small %>
<% match = HaveItem.find(result.incoming_item) %>
[...]

Good Examples (In both cases, this leaves the view with just HTML and some Ruby/Rails code inside):

Declare the variables in the controller action instead of the view

def action
  @result = Engine.results
  @match = HaveItem.find(@result.incoming_item)
  [...]
end

In case the view is a partial, declare the variables when calling the partial

<%= render :partial "match_results", :locals { :result => @result, :match => @match } %>

Of course, I'm not an expert on these things. Most of them are probably common sense to most people, but you'd be surprised how often these mistakes are actually made. I'm sure you all have seen these, or probably worse. Does anyone have any other tips that can be added? Feel free to leave a comment.

It’s As Easy As Working Your Ass Off

Posted on March 27th, 2008 in Opinion, Programming | View Comments

In the past couple of weeks, I’ve gotten incredibly addicted to Twitter, the micro-blogging, social-networking, chatting, or whatever you want to call it tool that’s been a huge hit in the past year or so. I had my account for a while, but never did anything with it. Recently I’ve just started following people and it’s just plain fun to see what these people are doing most of the time. I’m connected all the time now, so feel free to follow me! If you still don’t know what Twitter is, see a pretty cool video called Twitter in Plain English.

Well, I’m not here to talk about Twitter, although I’ve gone on and talked a fair bit about it. This post does have something to do with Twitter. I’ve been following a lot of people from the Rails community on Twitter (Geoffrey Grosenbach, Obie Fernandez, Dave Thomas, Jamis Buck and Rick Olson, among others). Some of the things they say are funny as hell (such as Obie’s “Po-po made me pour out my beer :( “), but for the most part they’re interesting stuff from these people. Most recently what I noticed is all the stuff these people actually do. They travel a whole lot, they meet a lot of interesting people and work on a ton of cool stuff.

My first thought when reading these comments are “Damn, these people are lucky to be doing all this stuff.” But in reality, I think they didn’t get lucky all of a sudden. Well, probably they had a little luck, but nonetheless it’s not pure luck. It seems like these people actually worked hard to get where they are now, and are probably still working hard to keep it going.

I always wondered why I couldn’t be the one working on awesome stuff, traveling to cool conferences and all that jazz. But making an honest assessment of myself, I definitely don’t work hard enough to earn these things. And it’s disappointing, because I know that if I put more effort into what I currently do now, I can achieve these things as well. Instead of picking up my Nintendo DS and playing The Legend Of Zelda: Phantom Hourglass for one or two hours straight, I could be starting formulating plans for some interesting ideas and projects I have in my mind. Instead of being on IM and chatting about non-significant things with people I don’t know in real life, I could be reading a book that will expand my knowledge. Instead of checking my RSS feeds every 20-30 minutes (like I obsessively do sometimes for no apparent reason), I could be helping with an open source project.

These are just a few of the things I can tweak to make more time for these things. I’m seriously going to try to change these things, even if it means less sleep and less playing Zelda – although I can’t promise anything when I get my Playstation 2 and Guitar Hero games sent from Puerto Rico, those games are more addicting than heroin. Anyway, I really want to start putting an honest effort to get myself more known out there, to do lots of things that other people will use, and to just help in any way possible those things I enjoy the most.

If you think like I thought before, it’s time to take a good look at yourself and see if the problem is that you’re truly unlucky, or if the problem lies simply in yourself.