Monday, December 26, 2011

How to automate copyright notice updates in Ruby on Rails

I sure hope everyone had a wonderful Christmas with their families. I am personally enjoying taking a few days off work and doing some reading.  On Christmas morning, I bought a copy of Rework (Kindle edition) by Jason Fried and David Heinemeier Hansson.  The "Go" Chapter alone is worth the price of admission!

One day I may share more about this book.  However, today it seems like a great time to share another Ruby on Rails coding trick with you.  That is how to automatically have your web apps update their copyright notices.

With only a few days remaining until the end of 2011, copyright notice update day is coming soon.  That is the day that many webmasters tweak the content of their page footers to reflect the new year.

However, suppose you wanted to automate the update process in a website written in Ruby on Rails.  Here is one way to do it with a simple layout helper function.

In helpers/layout_helper.rb:

def copyright_notice_year_range(start_year)
    # In case the input was not a number (nil.to_i will return a 0)
    start_year = start_year.to_i
 
    # Get the current year from the system
    current_year = Time.new.year 
    # When the current year is more recent than the start year, return a string
    # of a range (e.g., 2010 - 2012). Alternatively, as long as the start year
    # is reasonable, return it as a string. Otherwise, return the current year
    # from the system.
    if current_year > start_year && start_year > 2000
      "#{start_year} - #{current_year}"
    elsif start_year > 2000
      "#{start_year}"
    else
      "#{current_year}"
    end
  end
In layouts/application.html.erb (or your footer partial):
© <%= copyright_notice_year_range(2010) %> <%= link_to "YOUR COMPANY, INC.", "#" %>  All Rights Reserved.  
What is happening here?  The layout template calls copyright_notice_year_range, supplying the first year that the website was copyrighted as an integer.  The helper returns the string that should be shown after the copyright symbol.  Given the example above, on January 1, 2012, the notice will read:
© 2010 - 2012 YOUR COMPANY, INC.  All Rights Reserved.
Be sure to replace the # with your company's main website URL.

Here's wishing everyone a happy and prosperous 2012!

Wednesday, December 21, 2011

Conditionally Including Resources on SSL or non-SSL to Avoid Mixed Content Security Warnings in Ruby on Rails

When building content that can be delivered on an encrypted HTTPS connection it is necessary to reference all of the embedded resources, 3rd party badge images, embedded YouTube videos, etc, from an HTTPS url.  Otherwise a mixed content error will imply to your users that the website is not safe, ouch!

For instance, consider this YouTube video reference:
<iframe height="349" src="https://www.youtube.com/embed/P3LaGQciUXs?hl=en&fs=1" width="425"></iframe>
This works great when the page is loaded either over an SSL or a non-SSL connection.  The trouble is that the encrypted resource can take longer to load than a non-SSL resource because the user's browser has to negotiate a new encrypted connection with the third party server. When the security is needed this is good.  When it is not, this just increases the chance that the user will go away and never come back (How Loading Time Affects Your Bottom Line) - especially on a mobile device.

In a Ruby on Rails view, you can use the request.ssl? flag to conditionally supply either a https or a http for the external website reference, like this <%= request.ssl? ? "https://" : "http://" %>. In your Ruby HTML view (or partial) it would look something like this:
<iframe height="349" src="<%= request.ssl? ? "https://" : "http://" %>www.youtube.com/embed/P3LaGQciUXs?hl=en&fs=1" width="425"></iframe>
With that the video will be included as http:// on an non-SSL page and as https:// on an SSL page.

However, there is an even better way that does not require a ternary operator in your view.  While researching for this post I came across the protocol-releative URL reference in HTML (hat tip to Paul Irish).

The trick works like this:
<img src="//domain.com/img/logo.png" />
The same video could be included with:
<iframe height="349" src="//www.youtube.com/embed/P3LaGQciUXs?hl=en&fs=1" width="425"></iframe>
The only downside is that this might not work reliably in Internet Explorer 6.  If you care about IE6, you have to use the ternary conditional server-side code in your Rails HTML template.


Monday, December 19, 2011

Adding RANDOM alias to RAND in MySQL without Changing Ruby on Rails Code

While building the new website for www.sqlconverter.com, I recently ran into a slight compatibility issue between the SQLite3 database used for local initial development and MySQL when the site was prepared for production.  What was the compatibility issue?  It was the random function!

The issue popped up in the function used by the main page to return three random testimonials (in random order) for presentation on the homepage.  The RoR code for the function is:

In models/testimonial.rb:
def self.top_random
    number_to_return = 3
    Testimonial.find(:all, :limit => number_to_return, :order => "RANDOM()")
end

The highlighted ActiveRecord call more or less translates into this SQL:
SELECT * FROM testimonials ORDER BY RANDOM() LIMIT 3

The SQL server is expected to return three (3) entries in random order. It works great in SQLite and PostgreSQL.  It also works great in MySQL, except MySQL doesn't have RANDOM() but rather has a RAND() - which does the exact same thing.

However, I did not want to have to change the RoR code, which was already passing its unit tests.  Besides doing so would cause the code to not work in the other databases, which define the RANDOM function. The quickest solution turns out to be to define a custom RANDOM function for MySQL!

MySQL statement to define RANDOM() as an alias for its native RAND()
CREATE FUNCTION random() RETURNS FLOAT NO SQL SQL SECURITY INVOKER RETURN rand();

(This SQL statement was originally posted at Selecting random in rails sqlite vs mysql by Jason Weathered, thank you Jason!).

And everything worked.  I hope this will help you too.

Saturday, December 17, 2011

SQL Converter 2 for Excel Website Update

From My Company's Homepage:
Rietta is proud to announce that we have updated the website for SQL Converter for Excel at www.sqlconverter.com. Next year is the 10th anniversary of the initial public release of the program.
I originally wrote the Excel add-in that converts Excel files to MySQL while a student at Georgia Tech as a Visual Basic macro. Over the last nine (9) years it has been used by hundreds of customers in many industries, including by many small businesses, several publicly traded companies, government agencies, and educational institutions.

The current version is still a macro that works fine with Microsoft Excel for Windows, but it is time to build a solution that works for more platforms, including my personally preferred Mac OS X and Linux systems. To this end, we are currently working on a web-based service to provide cloud-based spreadsheet to database conversions.  However, the first step towards deploying the new service is migrating the current infrastructure to Ruby on Rails.

The original sqlconverter.com website was written in PHP and hosted on a typical shared Linux server environment, but the new one is entirely in Ruby on Rails 3.1. We setup the routing such that the old URL structure was maintained for search engine optimization (SEO) purposes. We also implemented canonical links to avoid duplicate content penalties due to the pages being accessed through more than one path. One of these days I should write a bit more about the tricks employed.

If you routinely work with spreadsheets provided by customers or team members and need to get that data into a MySQL database for your projects, please check SQL Converter out.  Also please feel free to let me know if you have any questions about it!

Thursday, December 15, 2011

SQLCONVERTER.COM Major Website Update

Rietta is proud to announce that we have updated the website for SQL Converter for Excel at www.sqlconverter.com. Next year is the 10th anniversary of the initial public release of the program.