A recent release of Bouldr threw a bit of a spanner in the works when the excellent Asset Packager began choking when attempting to create our concatenated and compressed javascript file.

It turns out that as I am developing in Windows (gah!), I need to run dos2unix in order to ensure that the js files are in the appropriate file format (our server is running CentOS). In order to automate this process, I added the following to our deploy script:


# Need to ensure files are in UNIX format for the asset packager to run correctly
run "cd #{release_path}/public/javascripts && find . -name '*.js' -exec dos2unix '{}' \\;"

# Run the asset packager to create the production javascript and css files
run "cd #{release_path} && rake asset:packager:build_all RAILS_ENV=production"

I recently came across a small problem in RSH whereby on loading a page with a state in the url (e.g. localhost.com/test_page#test) would not trigger the history listener function on it’s initial load. To fix this, I needed to modify my window onload function to include a call to my history listener, as follows:


history_listener: function (newLocation, historyData) {
...
},

// Window.onload calls this
initialize_history: function () {
       	dhtmlHistory.initialize();
       	dhtmlHistory.addListener(this.history_listener.bindAsEventListener(this));

       	// Added this line to force a call to my history listener
       	this.history_listener(dhtmlHistory.getCurrentLocation());
}

This ensures that when the page is freshly loaded, the history listener is called with the contents of our initial location.

This one had me for a while: When attempting to install the MySQL gem on my shiny new Slicehost slice, I was getting the folowing error:


Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
   ERROR: Failed to build gem native extension.

/usr/local/bin/ruby extconf.rb install mysql -- --with-mysql-include=/usr/include/mysql --with-mysql-lib=/usr/lib/mysql
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... yes
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
   --with-opt-dir
   --without-opt-dir
   --with-opt-include
   --without-opt-include=${opt-dir}/include
   --with-opt-lib
   --without-opt-lib=${opt-dir}/lib
   --with-make-prog
   --without-make-prog
   --srcdir=.
   --curdir
   --ruby=/usr/local/bin/ruby
   --with-mysql-config
   --without-mysql-config
   --with-mysql-dir
   --without-mysql-dir
   --with-mysql-include=${mysql-dir}/include
   --with-mysql-lib=${mysql-dir}/lib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-mlib
   --without-mlib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-zlib
   --without-zlib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-socketlib
   --without-socketlib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-nsllib
   --without-nsllib
   --with-mysqlclientlib
   --without-mysqlclientlib

Gem files will remain installed in /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7 for inspection.
Results logged to /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/gem_make.out

It turns out, all I needed was to run the following:


gem install mysql -- --with-mysql-config=/usr/bin/mysql_config

Hope this saves someone the hour or so I spent scratching my head!

OK, so say you have a form as follows:


<% form_tag '/', :method => :get do -%>
<p><%= text_field_tag 'q', params[:q] ||= '' %> <%= submit_tag 'Search' %></p>
<% end %>

That form will send the contents of the text box to the page at ‘/’. Unfortunately, it will also send through the value of the submit button, which is ‘Search’ in this case. The url generated will be:

/?q=something&commit=Search

In this case, we would want only the ‘q’ parameter passing through, and in order to do this, all we need do is nullify the name parameter:


<% form_tag '/', :method => :get do -%>
<p><%= text_field_tag 'q', params[:q] ||= '' %> <%= submit_tag 'Search', :name => nil %></p>
<% end %>

This will create the following url on submission:

/?q=something

Just a quick tip I recently came across:

If you want to see the docs for any of the gems installed on your dev machine, type the following in the command line…


gem_server

…and then browse over to http://localhost:8808/!

Railscasts are a Rails developers wet-dream.

Since Ryan created the site, it has been a fount of knowledge for anyone wishing to learn about the latest and greatest tips and tricks. To make things even better, they are free, though PeepCode is also very much worth a look for those of us wanting to glean a little (or a lot) of in-depth knowledge; $9 is a menial sum to pay for what amounts to a full-on lecture!

If you haven’t done already, go take a look - there is even a bunch of screencasts dedicated to Rails 2.0!

Given that the back button has been around for many years, and users have grown accustomed to it’s use, it’s a shame to see so many web applications neglecting this feature. As an example, I’ll pick on Lightbox, a tool that I like, yet one that is flawed in it’s disregard for the back button. For example:

  1. You navigate to a page that contains a thumbnailed image
  2. You click the image, and Lightbox shows it centered in your browser, full size
  3. You click back, press the back button on your mouse or whatever

Now, I realise that Lightbox has a close button in the image dialog box, but I’m not looking at the box, I’m looking at the image, and furthermore, my natural path back to the originating page is to press the back button, not to close the Lightbox. I therefore end up at the page I was on before I saw the thumbnail.

I’ve seen this with many users - the back button has been scarred into our mind, and to break it now is frivolous, and will ultimately lead to frustration, and lost users.

It’s with relief therefore, that I found Really Simple History, a JavaScript library for dealing with this exact problem - to create a JS history system that can run across many browsers, and provide developers with a little hope that our apps will no longer break the most fundamental user assumptions.

We tried to get the browser history working in Bouldr, and to an extent, we succeeded. The difference between coding something proprietary, and using an open source solution, though is very great indeed, so without doubt, we’ll be refactoring to use this library in the future.

From a business standpoint, Facebook’s killer feature is it’s Social Network, which gives even none-techies the ability to share nuggets of information found both on Facebook and the web at large with their friends.

What I didn’t realise until recently is that Facebook also allows businesses to set up pages inside the walled garden, that gives FB’s users the opportunity to show their support of your business by becoming ‘Fans’.

It doesn’t cost anything to set up a business page, which comes with a reporting tool that shows you just how many visits / page views / fans you’re getting per day, an update tool that allows you to send news items to your fans, and a bunch of advertising tools that you can use to promote your business page.

I set Bouldr up on the 21st November 2007 (check it out!), and already I have around 15 fans, with a slew of visitors coming from Facebook over to Bouldr’s main site. If you have a website that could benefit from a little social promotion, I’d suggest taking a look at Facebook’s business listing service - it’s free, so there is very little risk, really.

Symptoms

  • rake wouldn’t work
  • script/server wouldn’t run

# Logfile created on Wed Nov 21 13:39:25 +0000 2007 by /
DEPRECATION WARNING: observer is deprecated and will be removed from Rails 2.0  See http://www.rubyonrails.org/deprecation for details. (called from ./script/../config/../app/controllers/account_controller.rb:3)
DEPRECATION WARNING: depend_on is deprecated and will be removed from Rails 2.0  See http://www.rubyonrails.org/deprecation for details. (called from observer_without_deprecation at ./script/../config/../vendor/rails/actionpack/lib/action_controller/deprecated_dependencies.rb:29)
wrong number of arguments (1 for 0)
./script/../config/../vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:566:in `initialize'
./script/../config/../vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:566:in `new'
./script/../config/../vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:566:in `scramble41'
./script/../config/../vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:144:in `real_connect'
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:389:in `connect'
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:152:in `initialize'
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:82:in `new'
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:82:in `mysql_connection'
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/abstact/connection_specification.rb:262:in `send'
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/abstrct/connection_specification.rb:262:in `connection_without_query_cache='
./script/../config/../vendor/rails/activerecord/lib/active_record/query_cache.rb:54:in `connection='
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/abstrat/connection_specification.rb:230:in `retrieve_connection'
./script/../config/../vendor/rails/activerecord/lib/active_record/connection_adapters/abstrac/connection_specification.rb:78:in `connection'
./script/../config/../vendor/rails/activerecord/lib/active_record/base.rb:760:in `columns'
./script/../config/../vendor/rails/activerecord/lib/active_record/base.rb:768:in `columns_hash'
./script/../config/../vendor/rails/actionpack/lib/action_controller/session/active_record_store.rb:105:in `setup_sessid_compatibility!'
./script/../config/../vendor/rails/actionpack/lib/action_controller/session/active_record_store.rb:79:in `find_by_session_id'
./script/../config/../vendor/rails/actionpack/lib/action_controller/session/active_record_store.rb:283:in `initialize'
./script/../config/../vendor/rails/activerecord/lib/active_record/base.rb:864:in `silence'
./script/../config/../vendor/rails/actionpack/lib/action_controller/session/active_record_store.rb:283:in `initialize'
c:/ruby/lib/ruby/1.8/cgi/session.rb:273:in `new'
c:/ruby/lib/ruby/1.8/cgi/session.rb:273:in `initialize'
./script/../config/../vendor/rails/actionpack/lib/action_controller/cgi_process.rb:122:in `new'
./script/../config/../vendor/rails/actionpack/lib/action_controller/cgi_process.rb:122:in `session'
./script/../config/../vendor/rails/actionpack/lib/action_controller/cgi_process.rb:154:in `stale_session_check!'
./script/../config/../vendor/rails/actionpack/lib/action_controller/cgi_process.rb:109:in `session'
./script/../config/../vendor/rails/actionpack/lib/action_controller/base.rb:1052:in `assign_shortcuts_without_flash'
./script/../config/../vendor/rails/actionpack/lib/action_controller/flash.rb:140:in `assign_shortcuts'
./script/../config/../vendor/rails/actionpack/lib/action_controller/base.rb:424:in `process_without_filters'
./script/../config/../vendor/rails/actionpack/lib/action_controller/filters.rb:624:in `process_without_session_management_support'
./script/../config/../vendor/rails/actionpack/lib/action_controller/session_management.rb:114:in `process'
./script/../config/../vendor/rails/actionpack/lib/action_controller/base.rb:330:in `process'
./script/../config/../vendor/rails/railties/lib/dispatcher.rb:41:in `dispatch'
./script/../config/../vendor/rails/railties/lib/webrick_server.rb:113:in `handle_dispatch'
./script/../config/../vendor/rails/railties/lib/webrick_server.rb:79:in `service'
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
c:/ruby/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
c:/ruby/lib/ruby/1.8/webrick/server.rb:162:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
c:/ruby/lib/ruby/1.8/webrick/server.rb:95:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:92:in `each'
c:/ruby/lib/ruby/1.8/webrick/server.rb:92:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:23:in `start'
c:/ruby/lib/ruby/1.8/webrick/server.rb:82:in `start'
./script/../config/../vendor/rails/railties/lib/webrick_server.rb:63:in `dispatch'
./script/../config/../vendor/rails/railties/lib/commands/servers/webrick.rb:59
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
./script/../config/../vendor/rails/activesupport/lib/active_support/dependencies.rb:496:in `require'
./script/../config/../vendor/rails/activesupport/lib/active_support/dependencies.rb:343:in `new_constants_in'
./script/../config/../vendor/rails/activesupport/lib/active_support/dependencies.rb:496:in `require'
./script/../config/../vendor/rails/railties/lib/commands/server.rb:39
script/server:3:in `require'
script/server:3

Solution

Very simple - the machine that was running this app hadn’t got the mysql gem installed, therefore, simply running:


gem install mysql

sorted the problem out.

In protest at Total’s involvement in Burma, Mike Robertson solos the Eiffel Tower. (via)