Blog
what did i learn today
use %q to create strings

In my gemspec created by jeweler I saw string creating using %Q. What? [ruby] gem.summary = %Q{TODO: one-line summary of your gem} gem.description = %Q{TODO: longer description of your gem} [/ruby] I found a pagedescribing ruby string creation, and it seems %Q is the equivalent of double quote delimited strings and %q is the equivalent of single quotes. While i was pondering what the advantage could be of writing it that way, i opened up irb and look and behold: [ruby] irb(main):001:0> test = %Q{ggg gggg ggg} => "ggg gggg ggg" irb(main):002:0> test2= "ff ff ff" => "ff ff ff" irb(main):003:0> test= %Q{%q{ffff ffff ffff}} => "%q{ffff ffff ffff}" irb(main):004:0> test= %Q{this is a "test", curious whether 'it' works :)} => "this is a "test", curious whether 'it' works :)" irb(main):005:0> test= %Q{this is a "test", i am curious whether #{test2} 'it' works :)} => "this is a "test", i am curious whether ff ff ff 'it' works :)" irb(main):006:0> [/ruby] Cool! It allows you to write your strings without having to think about escaping the quotes.

easiest dual boot ubuntu install

I wanted to convert my XP laptop to a dual boot with Ubuntu or Kubuntu. Whichever. I want to try out linux and maybe switch altogether. Run windows inside a Virtualbox if i would really need it (e.g. for work). So i looked up different tutorials, while i was cleaning up disk-space and suddenly bumped into Wubi. I assumed i had to play with partitions and bootsectors, but the Wubi-installer manages all that for you. Just download the program (1.4MB!), run it, fill in a user and password and it takes all the work out of your hands. Completely automatic. Ideal for me ;)

script/plugin install from git fails

I am using ruby 1.8.7 on windows (mingw32), and all of a sudden i cannot run [ruby] c:\> ruby script/plugin install git://github.com/daphonz/dirty_associations.git Plugin not found: ["git://github.com/daphonz/dirty_associations.git"] [/ruby] the suggested variations also don't work, e.g. [ruby] ruby script/plugin install http://github.com/daphonz/dirty_associations.git ruby script/plugin install http://github.com/daphonz/dirty_associations.git/ [/ruby] all give the same error. But, apparently, it has something to do with the mingw32 platform. In C:\Ruby\lib\ruby\gems\1.8\gems\activesupport-2.3.5\lib\active_support\core_ext\kernel\reporting.rb the following line can be found in function silence_stream: [ruby] stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null') [/ruby] Replace that with the correct way to check for the windows platform, and then all should be fine again :) [ruby] stream.reopen(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null') [/ruby] I still needed to replace git:// with http:// but now it works :) Now investigate how this can be pushed to Rails codebase?

keeping observe_field and spinner in sync

I am using a lot of observe_fields in my views. I have two searches on my form, one with two fields one with four, and every time a user types something the observe_field is triggered and some search is executed via AJAX. To make sure the user knows what is going on, i use a spinner-image. [ruby] <%= observe_field 'querypeople', :frequency => 1, :update => 'people_to_link', :before => "Element.show('spinner2')", :loaded => "Element.hide('spinner2')", :complete => "Element.hide('spinner2')", :url => {:action => 'listpeople'}, :with => " 'querypeople=' +escape($('querypeople').value) + '&queryorganisation=' + escape($('queryorganisation').value)" %> <%= observe_field 'queryorganisation', :frequency => 1, :update => 'people_to_link', :before => "Element.show('spinner2')", :loaded => "Element.hide('spinner2')", :complete => "Element.hide('spinner2')", :url => {:action => 'listpeople'}, :with => " 'querypeople=' +escape($('querypeople').value) + '&queryorganisation=' + escape($('queryorganisation').value)" %> [/ruby] This works all fine and dandy, but when a user types multiple characters in a row, the spinner is hidden while another query is running. So i needed to improve that. I first introduced a little code to count how many times a certain spinner is shown: [ruby] <% javascript_tag do %> var spinner_counter=[0,0,0]; function show_spinner(itm) { spinner = (itm == 0) ? "spinner2" : "spinner" ; Element.show(spinner); spinner_counter[itm] = spinner_counter[itm] + 1; } function hide_spinner(itm) { spinner = (itm == 0) ? "spinner2" : "spinner" ; spinner_counter[itm] = spinner_counter[itm] - 1; if (spinner_counter[itm] <= 0) { Element.hide(spinner); spinner_counter[itm] = 0; } } <% end %> [/ruby] and then adapted the ruby-code as follows: [ruby] <%= observe_field 'querypeople', :frequency => 1, :update => 'people_to_link', :before => "show_spinner(0)", :complete => "hide_spinner(0)", :url => {:action => 'listpeople'}, :with => " 'querypeople=' +escape($('querypeople').value) + '&queryorganisation=' + escape($('queryorganisation').value)" %> <%= observe_field 'queryorganisation', :frequency => 1, :update => 'people_to_link', :before => "show_spinner(0)", :complete => "hide_spinner(0)", :url => {:action => 'listpeople'}, :with => " 'querypeople=' +escape($('querypeople').value) + '&queryorganisation=' + escape($('queryorganisation').value)" %> [/ruby] Do you know a better solution?

mongrel_service beta troubles with space

I am switching back from using thin inside a service to mongrel_service, because when my thin-process is killed somehow, the service stills seems to be running. Mongrel_service can cope with this much better: it also keeps a check on your ruby process and restarts it if needed (at least in the old version, i hope the 0.4.beta3 prerelease version behaves the same). When using the mongrel_service (gem install mongrel_service --pre) on ruby 1.8.7 you can no longer have a space inside the name. So if you run the following command: [bash] mongrel_rails service::install -N "Name with a space" -c c:\path\to\your\app -p 4000 -e production [/bash] there will be no output as to whether it succeeded or not on XP, on Windows Server 2008 a more appropriate error is shown; but the service will not be created. The trouble is the name: it contains a space, and apparently that is no longer allowed. On the old MRI and previous mongrel_service it was not a problem. The old version, however, does not work in ruby 1.8.7 from rubyinstaller.org, due to a dependency to some very specific Visual C++ code regarding service communication (and now the ruby is compiled using gcc). Luckily there is an easy fix, as suggested by Luis Lavena himself: [bash] mongrel_rails service::install -N name_without_space -D "Name with a space" -c c:\path\to\your\app -p 4000 -e production [/bash]

accessing current_user in models

Up until now i was able to somehow circumvent the need to access the current-user in the model, by calling methods from the controllers and handing down the current-user. In the MVC pattern, the model should know as little as possible about things the controller handles. But now, i need a method that will check :before_save what has changed, and by whom, and will log that into another table (model). So i am going to create an Observerclass, that needs to access the model on the one hand, but needs to know the current-user on the other hand. First I found a very dirty but working solution. Put this in application.rb: [ruby] around_filter :you_dont_have_bloody_clue protected def you_dont_have_bloody_clue klasses = [ActiveRecord::Base, ActiveRecord::Base.class] methods = ["session", "cookies", "params", "request"] methods.each do |shenanigan| oops = instance_variable_get(:"@_#{shenanigan}") klasses.each do |klass| klass.send(:define_method, shenanigan, proc { oops }) end end yield methods.each do |shenanigan| klasses.each do |klass| klass.send :remove_method, shenanigan end end end [/ruby] This was credited to Pratik Naik, but at the same time highly NOT recommended by him. It seems a bit like a bulldozer approach. Actually it is nice to know such things are possible, and how to achieve it, but it (kind of) breaks the MVC pattern. So i looked further for a nicer solution. I found a really simple one here, and adapted it to my needs: [ruby] class User < ActiveRecord::Base cattr_accessor :current_user def self.current_user @current_user ||= User.new("dummy-user") end ... end class ApplicationController < ActionController::Base include AuthenticatedSystem before_filter { |c| User.current_user = session[:user] } end [/ruby] And now, inside each class, i can just use [ruby]User.current_user[/ruby]. I overwrite the current_user class method, so i don't have to set the user manually during tests (is that clean?). I am not sure if this is the best solution. I found a few more complicated ones, but this seems to fit me the best.

Arrrrcamp

Went to arrrrcamp last friday (Arrrr as in _R_uby, _R_ails, _R_adiant and, of course, _R_hum!). It was the third edition of this unique ruby-on-rails event, and the third time i visited it ;) So i am a regular :) The first year i was just starting ruby and my then-collegue and me learned a lot. The second time i took some new collegues along hoping to get them infected with the ruby virus. This year i went alone (so you can guess how well the infection spread :), but one advantage of being alone in a croud is that it is way easier to mingle. There's even a picture to prove it :) I saw some very interesting talks:

  • Something Something Mongo: I alrready had read about Mongo, and was interested. This speech interested me more than Radiant. Just another NoSQL database. Some things were not entirely clear, like how you can query stuff if all things are in the same "database". But it seems like something i should investigate more. I think there are a lot of possible applications, and the presenter showed a very good example, where the database is entirely configurable by the end-user, which is dead-easy in Mongo and MongoMapper, because there is no schema! Ha! :) Opens up possibilities indeed ;)
  • jQuery on Rails: at the same time there was a talk about the new things in Rails3. So this was a hard choice. But i am already using jQuery, in combination with Prototype, and was hoping to get some tips to do it better. The talk was very quick, but also very informative. The presenter did a very cool job, where he showed the same site in Prototype (using helpers) and jQuery (using unobtrusive javascript). Very nice. I still write most of my javascript inline, and am gradually switching over. I am still struggling with one problem. In most of unobtrusive javascript examples, i always see that all code is placed in the application.js. But that is not good enough for me. I want a js file per erb-file. I found a blogpost by Yehuda Katz, where he does something even smarter: only include the js-files which include the selectors from the current page. But unfortunately it is so old, the source is nowhere to be found anymore. when i asked the presenter, after the session, he pointed me to this article about Jzip, but on second look it is not quite what i am looking for.
  • Railties: what, why & how?: a very interesting talk, but i must admit, since Rails 3 territory is still very unknown to me (and a lot has changed apparently) a lot of it was unclear. In short: the old way to create rails plugins is replaced by Railties. Plugins and engines are supported, dependencies are more explicit. Something i still need to look into, to convert the plugin we use at work.
  • Something something Rack: actually i did not want to see this one, but rather the 12 hours to rate a rails website by Elise Huard, but because @Atog was late those two talks had switched. She confided, however, that i would get a second change at RailsConf :) The something-something-rack talk was very basic, but also enlightning. Rack provides a minimal interface between webservers supporting Ruby and Ruby frameworks. Rack applications can be stacked. Since Rails is a Rack application, it is now very easy to put Rack-apps in front of Rails, for instance to redirect to different sites or pages if the visitor uses a mobile device (Rack::MobileDetect), add google analytics to your pages automatically (Rack::GoogleAnalytics), or to block unallowed access (Rack::Warden). Very interesting. Also allows for a clean seperation of concerns. One last Rack middleware I really want to mention: Rack::ChromeFrame! This middleware will make sure the Google Chrome frame is automatically enabled. Cool :)
  • Learning to smile at your code: a talk by two german guys, who both work at Xing, about refactoring and to learn to actually enjoy it. Xing is a very big website, coded for the largest part in Rails. They have 22 developers working in Rails. Sebastian and Tim, the presenters, had to add features to the job-postings page/code and encountered a lot of problems doing so. I really liked this talk because i found it very recognisable and also because it was a talk focusing on the programming of an application as a whole. They used a lot of humour to convey their message, with success. Really-really compressed their message was: 1) seeing a lot of old, incomprehensible code can be demotivating; 2) breathe and relax; 3) starting to refactor it anyway, despite the obvious unwillingness at first, will make you smile because you can create something beautiful. They gave some examples which i guess barely even scratched the surface of the complexity they had to deal with. Nice :) After that the lightning talks came (short talks of about 10 minutes). I will highlight a few:
  • failtale: a notification framework/website by the guys from Mr. Henry. Impressive, because not only does it capture ruby/rails exceptions, but also ActionScript (flash) and Javascript soon. I am going to try that out! :) I am currently using Exception Notifier myself, curious how it compares.
  • The guys from 10-forward did three talks. First a demo of their application, which was incredibly impressive. Wow! Blew me away. A lot of javascript and ajax to make the website feel like a real application. Very powerful. Then they discussed a gem of theirs, and rspec and cucumber.
  • wallsome: Sebastian and Tim from Xing, who also did the Learning to smile talk, here presented their pet-project, using Rails 3 and jQuery: a wall to arrange your tasks from Basecamp like in Scrum or Kanban. I am looking forward to the next edition on the 29th of october! :)
setting word bookmarks from ruby

The easy solution to set a bookmark inside a Word-document: [ruby] require 'win32ole' word = WIN32OLE.new('Word.Application') doc = word.Documents.Add("#{path to your template here}") doc.Bookmarks("bookmark-name").Range.Text = "new content here" [/ruby] This will work, and will replace the bookmark with the text you wanted to insert. Recently i had to convert a document that was first built using mail-merge. I am not very familiar with mail-merge, but it seems a specific field can occur multiple times inside the document. This is very convenient. So i looked for a way to replace this behaviour, and still use bookmarks. I know how to set bookmarks programmatically, and this seemed easier than preparing a temporary document first for mail-merging. My first thought was that i create bookmarks, and give the duplicate bookmarks names like "#{original -bookmark-name}_2" , and inside my program i would go looking if there would be any copies (_2, _3, _4) and set them accordingly. But i looked further. There should be a better way. Luckily there does exist something called "REF" fields inside Word, which are fields that inherit their content from a certain bookmark! A-ha! But the above code won't work, because i actually replace the bookmark with the text, and then nothing is left to be reffered to :) So the code to set a bookmark turns a bit more complex: [ruby] require 'win32ole' word=WIN32OLE.new('Word.Application') doc = word.Documents.Add("#{your-template-path}") ## wdGoToBookmark = -1, wdCharacter = 1 word.Selection.GoTo("What" => -1, "Name" => "#{your-bookmark-name}") word.Selection.Delete("Unit" => 1, "Count" => 1) word.Selection.InsertAfter "#{your-new-text}" # re-create our bookmark doc.Bookmarks.Add("Range" => word.Selection.Range, "Name" => "#{your-bookmark-name}") # update all (referring) fields doc.Fields.Update # in Word2007, filetype 16 saves as a Word2003 compatible document, 12 is docx, 17 is pdf doc.SaveAs "#{your-filename}.doc", 16 [/ruby] [UPDATE] Actually, although this works, it doesn't work if two bookmarks are really close, e.g. only seperated by a single space. So the above is not the correct way. Some googling revealed the correct way: [ruby] # new version of code bm_name = "#{your-bookmark-name}" bm_range = doc.Bookmarks(bm_name).Range bm_range.Text = "insert something interesting here" doc.Bookmarks.Add bm_name, bm_range [/ruby] I hope this helps :)

So i am developing and deploying Ruby on Rails applications on Windows. Recently i started experimenting with the newer versions of ruby (mingw32platform). One of the side-effects is that the mongrel-service, which i always used to deploy my rails-applications no longer works on mingw32. And aside of that, i have read on various instances [ref] that thin should be better (more efficient) than mongrel. But i still want to install it as a service. First off, you need to download and install the Windows Resource Kit. This contains the executables to make a service of any executable or script. Then create the service running (in the console): [bash] C:\Program Files\Windows Resource Kits\Tools> instsrv "[my_service_name]" "c:\program files\Windows Resource Kits\Tools\srvany.exe" The service was successfuly added! Make sure that you go into the Control Panel and use the Services applet to change the Account Name and Password that this newly installed service will use for its Security Context. [/bash] This will add an empty entry in the registry, which actually still does nothing. To get it working, we have to start regedit, and navigate to the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services[my_service_name] Create a new key (folder) named Parameters. This will contain the settings of our actual application that will be run as a service. Add the following String Values: [bash] [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services[my_service_name]\Parameters] Application=c:\ruby\bin\ruby.exe AppDirectory=[my_ruby_app_folder] AppParameters=c:\ruby\bin\thin start -p 4000 -e production [/bash] Assuming that c:\ruby\bin is your ruby folder, and you want your thin to listen to port 4000. Once that is done, start the service, and your rails application should be up and running :)

... but Windows Server 2008

Unfortunately, to do this on Windows 2008 you need to perform some extra steps. As you can't install the resource kit on Windows Server 2008R2 for some peculiar reason, and at the time of this posting, i have not found a Windows Server 2008 Resource Kit Tools, so i took the following steps:

  1. copy the "srvany.exe " from the "Windows Server 2003 Resource Kit Tools " to a suitable location on your Win2008 server (e.g. C:\Windows\System32\ )
  2. use "sc " to create a new service that launches "srvany " (e.g. sc create MyService binPath= C:\Windows\System32\srvany.exe DisplayName= "My Custom Service" )
  3. using RegEdit create a "Parameters " key for your service as before and fill it with the 3 string values A bit more work, but not too much.

mongrel-service?

And just today I discovered an update of mongrel_service was announced, so you can still work using mongrel_service instead of using thin and manually creating the service. What you need to do:

  • install mongrel service: gem install mongrel_service --prerelease
  • create the service as before: mongrel_rails service::install -N myapp -c c:\my\path\to\myapp -p 4000 -e production That is much easier of course.

working on Windows Server 2008R2 64-bit, installing ruby 1.8.7, ruby-oci8 ran into the following error, after requiring 'oci8' : LoadError 193: %1 is not a valid Win32 applicationOn this machine a 64bit version of Oracle was installed. So the OCI.dll was a 64-bit version. The fix seemed easy: copy a 32-bit version of the OCI.dll. But I had to copy (from another 32-bit machine)

  • OCI.dll (32-bit)
  • MSVCR71.dll
  • ... and ORAOCIEI10.dll

to my ruby\bin folder, and then everything worked. Copying just the OCI.dll and MSVCR71.dll gave the puzzling error OCIError: OCI library initialization error.

refactoring ruby code

Most of my ruby/rails development is against a legacy Oracle database. One of the things we needed to fix, was a user-table with not enough fields. Because the user table was shared with another application, we were not able to alter the table. So we added another table, user_params, containing possibly extra parameters for each user. Now it would be nice if each of those possible parameters would behave like a real attribute. So, first implementation: [ruby] class User < ActiveRecord::Base set_primary_key "user_name" set_table_name "stca_user" set_sequence_name "autogenerated" # do not use a sequence at insert! validates_presence_of :user_name validates_presence_of :password # define some virtual attributes for attributes defined in the UserParam table def group_name UserParam.get_param_value(self.user_name, 'UserGroup') end def group_name=(value) UserParam.set_param_value(self.user_name, 'UserGroup', value) end def title UserParam.get_param_value(self.user_name, 'UserTitle') end def title=(value) UserParam.set_param_value(self.user_name, 'UserTitle', value) end def language UserParam.get_param_value(self.user_name, 'UserLanguage') end def language=(value) UserParam.set_param_value(self.user_name, 'UserLanguage', value) end def full_name UserParam.get_param_value(self.user_name, 'UserFullName') end def full_name=(value) UserParam.set_param_value(self.user_name, 'UserFullName', value) end def email UserParam.get_param_value(self.user_name, 'UserEmail') end def email=(value) UserParam.set_param_value(self.user_name, 'UserEmail', value) end # ... snipped away more code end [/ruby] Obviously, this code is not DRY. At lot of repetition, like the stuff i hate about C# or java properties. This could be done better, let's just generate the methods: [ruby] class User < ActiveRecord::Base set_primary_key "user_name" set_table_name "stca_user" set_sequence_name "autogenerated" # do not use a sequence at insert! validates_presence_of :user_name validates_presence_of :password # define some virtual attributes for attributes defined in the UserParam table instance_eval do [['group_name', 'UserGroup'], ['title', 'UserTitle'], ['language','UserLanguage'], ['full_name', 'UserFullName'], ['email', 'UserEmail']].each do |arr| define_method arr[0].to_sym do UserParam.send('get_param_value', self.user_name, arr[1]) end define_method "#{arr[0]}=" do |value| UserParam.send("set_param_value", self.user_name, arr[1], value) end end end end [/ruby] This looks nice. One disadvantage might be that this is not very readable. At first glance it is no longer clear which attributes are available. But with models that is always the case. A few things can still be improved. Every get and set is a query against the database. We might want to improve upon that, and cache results. Also saving the virtual fields is now done when they are being set, but at that time the parent "User" might still not be saved. So this still calls for a better solution. But this does show why i like ruby so much. It makes me feel powerful :)

When using Rails on top of an Oracle database, you use the oracle enhanced activerecord adapter. This adapter (or Rails) has one weird side-effect: there is no way to avoid using a sequence when inserting a new record. But, in this comment, Raimonds Simanovskis hints at the solution. In an initializer you write: [ruby] # a small patch as proposed by the author of OracleEnhancedAdapter: http://blog.rayapps.com/2008/05/13/activerecord-oracle-enhanced-adapter/#comment-240 # if a ActiveRecord model has a sequence with name "autogenerated", the id will not be filled in from any sequence ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do alias_method :orig_next_sequence_value, :next_sequence_value def next_sequence_value(sequence_name) if sequence_name == 'autogenerated' # we assume id must have gotten a good value before insert! id else orig_next_sequence_value(sequence_name) end end end [/ruby] ... and in your model you add: [ruby] set_sequence_name 'autogenerated' [/ruby]

multiple ruby versions on windows

I started developing ruby more than a year ago, on windows, which might not be the ideal platform :) But i started out with the standard one-click installer, ruby version 1.8.6, which up until recently served me fine and is an easy way to start. But when i felt the need to install metric_fu, i found out it just does not install on top of the old ruby 1.8.6 (mswin32). Now i know that for ruby 1.8.7 (mingw32) a development kit exists, which would allow compilation of all native code. So, normally, all plugins that were giving me problems before (e.g. thin!) should be able to be installed using that. Also the new rubyinstaller versions are known to be quicker, because they are using a more recent and efficient compiler (mingw), and ruby 1.9.1 should inherently be even more efficient (by design). But i was looking for an easy way to migrate and test ruby versions. I know that there exist a ruby version manager (rvm), but it only works on linux and mac. But luckily, for windows, there is pik. It is really easy to install: [bash] > gem install pik > pik_install c:\windows\system32 [/bash] [the choice to use windows\system32 is maybe not entirely kosher, but it is an easy way to add something to the path, always ;) Maybe i should have used c:\ruby\pik\bin and added that to the path.] Then add the current version as the default: [bash] > ruby -v ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32] > pik add Adding: 186: ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32] Located at: c:/ruby/bin [/bash] Then you can download the new versions, e.g. ruby 1.8.7. and 1.9.1 from rubyinstaller and install them each into their own folder. E.g. c:\ruby\187-p249\ and then issue the following command: [bash] > pik add c:\ruby\1.8.7-p249\bin ... > pik add c:\ruby\1.9.1-p378\bin ** Adding: 191: ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-mingw32] Located at: c:\ruby\1.9.1-p378\bin > pik list 186: ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32] * 187: ruby 1.8.7 (2010-01-10 patchlevel 249) [i386-mingw32] 191: ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-mingw32] [/bash] But of course, the second problem is that the one-click installer also includes a lot gems by default, while the new rubyinstaller is almost empty. So first i installed the development kit from rubyinstaller. I needed to extract that inside the each ruby folder, and change a few settings (configure), like described here, i needed to edit my /devkit/msys/1.0.11/etc/fstab settings file, and replace c:\ruby by my actual ruby-installation folder, in my case something like c:\ruby\1.8.7-p249. I create a small batch-file to install all the missing gems: [bash] rem default windows gems call gem install win32-api call gem install win32-clipboard call gem install win32-dir call gem install win32-eventlog call gem install win32-file call gem install win32-file-stat call gem install win32-process call gem install win32-sapi call gem install win32-service call gem install win32-sound call gem install win32console call gem install windows-api call gem install windows-pr call gem install hpricot call gem install nokogiri call gem install wxruby rem RAILS call gem install rails call gem install will_paginate call gem install mongrel call gem install mongrel_service call gem install formtastic rem database gems call gem install sqlite3-ruby call gem install ruby-oci8 call gem install activerecord-oracle_enhanced-adapter call gem install builder call gem install calendar_date_select call gem install cgi_multipart_eof_fix call gem install composite_primary_keys call gem install log4r call gem install ezcrypto rem testing call gem install cucumber call gem install cucumber-rails call gem install factory_girl call gem install remarkable call gem install rspec call gem install rspec-rails [/bash] But i still encountered an error on the gems that needed to build native extensions: [bash] C:\WINDOWS>gem install hpricot Building native extensions. This could take a while... ERROR: Error installing hpricot: ERROR: Failed to build gem native extension. c:/Ruby/1.9.1-p378/bin/ruby.exe extconf.rb checking for stdio.h... yes creating Makefile make MAKE Version 5.2 Copyright (c) 1987, 2000 Borland Fatal: '/c/Ruby/1.9.1-p378/include/ruby-1.9.1/ruby.h' does not exist - don't know how to make it Gem files will remain installed in c:/Ruby/1.9.1-p378/lib/ruby/gems/1.9.1/gems/hpricot-0.8.2 for inspection. Results logged to c:/Ruby/1.9.1-p378/lib/ruby/gems/1.9.1/gems/hpricot-0.8.2/ext/fast_xs/gem_make.out [/bash] It took a good nights rest to figure that one out: i have Borland's Cbuilder 5 installed on my system to be able to maintain ancient software. So i had to remove that entry from my path, and after that all gems that needed native building went smoothly, except mongrel_service. Now everything installed just fine, inside my 1.8.7 system. Doing the same on ruby 1.9.1 took a lot longer, or so it seemed definitely. I think partly that is because ruby 1.9.1 seems to maintain a class cache? But i am not sure of that. But what surprised me even more is that actually all gems installed without any problem, except win32-service and because of that, mongrel_service. As explained here, this issue is known and due to the fact that the library relies on specific MSVC behaviour that mingw does not support. But i think i can create a service from about any executable or batch file. But i read herethat i have to issue the following command: [bash] c:\ruby> gem install mongrel_service --prerelease [/bash] The pre-release version removes the dependency of win32-service, and so it works again. So now i can start testing my applications inside 1.8.7 and 1.9.1 on windows, try using thin, and get metric_fu up and running.

exception notifier configuration troubles

I installed and configured exception notifier to be notified of any unexpected errors in our production environment. At first i tried this out in development, used gmail as my smtp server and all was working fine. My action mailer configuration looked as follows, in environment.rb: [ruby] # configure mailing config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :enable_starttls_auto => true, :address => "smtp.gmail.com", :port => "587", :domain => "localhost", :authentication => :plain, :user_name => "<snipped>", :password => "<snipped>" } ExceptionNotifier.exception_recipients = %w(bla@my_clients_domain.com) ExceptionNotifier.sender_address = %("<snipped>@gmail.com") ExceptionNotifier.email_prefix = "[My Application ERROR] " [/ruby] Using this configuration worked, and i received the e-mails. Alas, as usual, on my client's production server the port to reach gmail was blocked, and when i asked to open it, they instead proposed to use their own smtp-server. So i changed the configuration as follows: [ruby] config.action_mailer.smtp_settings = { :address => "192.168.0.10", :port => "25", :domain => "production-domain.be", :authentication => nil } ExceptionNotifier.exception_recipients = %w(bla@my_clients_domain.com) ExceptionNotifier.sender_address = %("info@production-domain.com") ExceptionNotifier.email_prefix = "[My Application ERROR] " [/ruby] The first thing i did wrong was the domain-name. At first i wrote "@production-domain.be" in my action-mailer configuration, so my HELO request was blocked. Secondly, apparently, because i wrote ExceptionNotifier.sender_address = %("info@production-domain.com") the sender address was not recognised and the mail was rejected by our own SMTP-server. This took me a while to figure out. Luckily our sys-admin noticed the difference. The fix: [ruby] ExceptionNotifier.sender_address = %(info@production-domain.com) [/ruby] And now i know for sure that if i get no mails, my application really is working :)

observe_field in IE8: endless loop

My users showed me the weirdest problem today. In my application is a select-box that allows users to select the classification. When the classification is changed, the div containing the icons for the actions (and the classification-select-box itself) is updated to reflect the new classification. So i use an observe_field to watch the select-box, and trigger some javascript to perform the magic. In Firefox this works perfectly. But my users tend to use IE8, for some obscure reason, and switching to FF or Chrome is ... difficult (What other browser?). The observe_field is written as follows: [ruby] <%= observe_field "mention_thm_classification", :frequency => 0.5, :update => "mention-actions", :with => "classification_id", :before => "Element.show('spinner_cl')", :loaded => "Element.hide('spinner_cl')", :complete => "Element.hide('spinner_cl')", :url => { :action => "set_classification", :id => mention } %> [/ruby] Pretty straightforward. The observe_field is contained inside the div that is updated. When in IE8 a new value is chosen, i get the correct value in my method first, and then i get a whole bunch of classification_id="null". I am guessing what happens is that when the html is updated, somehow also the select-box is emptied, and thus changed, and thus a new value is triggered. So i replace the html again, and the select-box is emptied again, and an endless loop is born. So, the easy solution should be: do not do the action of the observe_field if the value of the select-box is null, and that is actually really easy: [ruby highlight="3"] <%= observe_field "mention_thm_classification", :frequency => 0.5, :update => "mention-actions", :with => "classification_id", :condition => "value != null", :before => "Element.show('spinner_cl')", :loaded => "Element.hide('spinner_cl')", :complete => "Element.hide('spinner_cl')", :url => { :action => "set_classification", :id => mention } %> [/ruby] We add a :condition that checks just that! It still feels i am doing something wrong, that i should not have to do this, so i would be happy to hear any way to improve this.

using content_for jquery on document ready

In my Rails application i use a generic application.rhtml for all my pages. Amongst others, this code contains some jQuery code to manipulate my page [javascript] var $j = jQuery.noConflict() $j(document).ready(function() { // remove all alt-tags $j("[alt]").removeAttr("alt"); // validate all forms $j("form").validate({ errorPlacement: function(error, element) { error.appendTo( element.parent() ); }}); }); [/javascript] The things i do in my document ready callback is simple: remove the alt attribute everywhere, so my tooltips will work on my links containing images, and if there is a form on the page i validate it. Now for one form, i need to add special code, so that when a user fills something in a field, a select-box looses some options. The ideal place to do this, is in the document ready. But not for all pages. How do i solve this in some elegant way, and not use a different layout for that page. I choose to use yield and content_for. Like this. Add the following line : [javascript] var $j = jQuery.noConflict() $j(document).ready(function() { // remove all alt-tags $j("[alt]").removeAttr("alt"); <%= yield :script %> // validate all forms $j("form").validate({ errorPlacement: function(error, element) { error.appendTo( element.parent() ); }}); }); [/javascript] and in my view i write: [ruby] <% content_for :script do %> var allOptions = $j('#mention_thm_classification option').clone(); $j('#mention_thm_reference_local').change(function() { var filter_txt = '.ref-'; if (!$j(this).val()) { filter_txt = filter_txt + 'empty'; } else { filter_txt = filter_txt + 'filled'; }; $j('#mention_thm_classification').html(allOptions.filter(filter_txt)); }); <% end %> [/ruby] So what i actually do is, check whether the value of a field changes. When it contains something a select-list with id mention_thm_classification is changed, and only the options with the correct class are kept. For completeness, my select is built as follows: [html] <select name="mention[thm_classification]" id="mention_thm_classification" > <option value='1' style='background-color: #b7f9e2' class="ref-empty " >Green</option> <option value='2' style='background-color: #ffdebb' class="ref-empty " >Orange</option> <option value='3' style='background-color: #ffbbc6' class="ref-empty ref-filled" selected="selected">Red</option></select> [/html] So i have described a nice way to add extra code to my document ready function without needing a special layout-page. And experienced for the umpteenth time how great jQuery is.

I am using the jQuery validate plugin which is awesome for straightforward form validation. What i especially like is that it offers the user a better user experience, because there is no need for the round-trip to the server. I still need to do the validation on the server-side (rails) as well. I guess there should be a way to extract the validations from the model into the view transparently, but for now i just add a class "required" myself. Now i did bump into a seemingly difficult problem, when the user wanted my to validate to having either one of both fields filled in. Luckily google came up with a beautiful answer quick enough! I needed to adapt it somewhat, because my form-styling places each label-field combination inside a div, so i search for the second surrounding 'div' (containing the group of fields for which only one field is required). [javascript] jQuery.validator.addMethod('required_group', function(val, el) { var $module = $j(el).parent('div').parent('div'); return $module.find('.required_group:filled').length; }, 'Please fill out at least one of these fields'); [/javascript] How i love the jQuery and Rails community. Awesome!

javascript open popups and firefox

In my Rails application, at a certain stage, it was necessary that my user performs an operation in another web-application (a GIS application) on the same database. I am using the following piece of code to make sure that i open a url in a new window, and that it should get the focus (jump to the front). [javascript] <% javascript_tag do -%> function newWindow(newContent, windowName) { var new_window; var new_window = window.open(newContent, windowName); if (window.focus) new_window.focus(); } window.onload=function() { newWindow('<%= link_to_location @mention, true %>', '<%= @gisapp_window_name %>'); setTimeout(jump_to_select_tab_url, 2000); } <% end -%> [/javascript] All is well when the window is first opened, but if the window was already opened, still it fails. And of course i do all testing against firefox 3.5, although my user wants to use IE instead. So i try in IE and it works. Huh? So it has something to do with Firefox 3.5. And behold, as explained here, firefox is so smart it will block all javascript manipulation of windows, which is of course just what we need in this case. So inside firefox, i need to go to Options->Content->Javascript and make sure that i can run javascript that will manipulate opening and closing of windows. Done!

insert javascript using link_to_function

I am using Rails 2.3.4 at the moment, and as is well known, rails uses Prototype as default javascript library. For most purposes this suits me well. But what i really like about jQuery is the wealth of plugins readily available. My solution was not something like jRails, but i use them side by side. This might not be the best solution :) First of, you have to include the correct javascript files. Then, at the top of my application.rhtml, i write this: [javascript] var $j = jQuery.noConflict() $j(document).ready(function() { /* insert some jquery magic here */ ... }); [/javascript] This ensures that i can use the jQuery library nicely alongside the Prototype one. Just replace $ by $j for all jQuery calls. For most jQuery things this is more than enough. But then I needed form validation, and needed to be able to call some jQuery from inside a link_to_function block. It took me a while to find, but actually (isn't it always) it is dead-simple. [ruby] def add_document_link(divname, parentdoc ) link_to_function get_icon('adddocument'), { :title => t('adddocument')} do |page| new_doc = Document.new new_doc.doc_ident_p = parentdoc.doc_ident page.select('.add-items-link').each { |b| b.hide } page.insert_html :bottom, divname, :partial => 'documents/add_document', :object => new_doc, :locals => { :divname => "add-items-link"} page << "var $j = jQuery.noConflict(); $j("form").validate();" end end [/ruby] Easy as pie :) I love rails :)

missing 'a' with rspec and cucumber

I am developing Ruby on Rails on Windows platforms mostly. But using Rspec and cucumber on windows has a very strange side-effect: all a's are missing as can be seen from the following screenshot: rspec-without-a-smallerLuckily, after some very extensive googling, i found a single blogpost with a fix! Apparently it has something to do with UTF-8 encoding, and the simple solution is that you need to change the encoding of the current command prompt. This can be achieved via a simple call before you start: [sourcecode] chcp 1252 [/sourcecode] The aforementioned post then proposes to adjust the cucumber.bat to not have to type this every time. This is all good for cucumber, but not for rspec, and anyhow, every new update of the cucumber i would need to apply this fix again. I was thinking that it might be possible to set the default codepage, which is 850 on my machine, to 1252 permanently. As this blogpost mentions, there are two different ways to achieve the wanted result.

Change the codepage system-wide

This can be done in the registry. [sourcecode] [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage] OEMCP=1252 [/sourcecode] But one commenter notes this is not without risk.

Only for command prompt

An alternative way is to put make sure that each time a console is opened (cmd.exe) the codepage is set automatically. [sourcecode] [HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor] Autorun=chcp 1252 [/sourcecode] This will only work for console windows in which you run cmd.exe, which is just what i needed.