Blog
what did i learn today
actionmailer attachments on windows

I have been having troubles sending e-mails using ActionMailer on windows. The simple code-sample: [ruby] my_filename="my_image.jpeg" attachment "image/jpeg" do |a| a.body = File.read(my_filename) a.filename = File.basename(my_filename) end [/ruby] did not work. I did find an attachment inside my e-mail, but it was corrupt. It took me a while to figure out it could be something related to my development platform, which unfortunately still is windows (not for long). On windows reading binary files is less obvious, apparently, so you need to write: [ruby] my_filename="my_image.jpeg" attachment "image/jpeg" do |a| a.body = File.open(my_filename,'rb') { |f| f.read} a.filename = File.basename(my_filename) end [/ruby] ... and this will work! :) I you have to combine normal e-mail content and one or more attachments, this then becomes something like: [ruby] # we send a mail to respond to a mention def mention_response(given_subject, addressee, pdf_attachment = nil) from APP_CONFIG["mail"]["from"] recipients addressee.to_a subject given_subject content_type "multipart/mixed" part "text/html" do |p| p.body = render_message("mention_response", :thr_name => thr_name) end attachment :content_type => "application/doc" do |a| a.filename File.basename(pdf_attachment) a.body File.open(pdf_attachment, "rb") { |f| f.read } end unless pdf_attachment.nil? end [/ruby] Nice :)

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! :)
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.

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.

I am now working in Ruby on Rails for about a month. I have done a few smaller things before, investigating, trying out; but now I am really building a full application site in Rails! It feels great :) But of course, just starting out in such a new environment, both ruby and rails, I encountered a lot of initial problems. One of them is showing international, accented characters, like é, è, ê ... from the database. Nor Rails nor irb could show the correct characters. I really needed to solve this problem, so this started an investigative journey.

The symptoms

When displaying a table of results from Rails in any browser, all accented characters were shown as white question marks inside a black rhombus (diamond?). When i tested this with irb i also got very weird results. When using TOAD the results of a query are displayed correctly. But maybe TOAD just does it very clever? If i use the GUI version of SQL*Plus (sqlplusw) the results are also shown correctly. But when i use the console (command-line) version of sqlplus, the characters were also distorted. So maybe the clue could be found there.

Oracle NLS-LANG

No matter what character-set the Oracle database uses to store the data (e.g. UTF-8, UTF-16) the data is always converted to the clients character set. This is truly an amazing feature. This depends on a setting called NLS_LANG. Not sure wat it quite stands for. NLS_LANG is built up as follows:NLS_LANG=language_territory.charsetThe NLS_LANG property is set by default in the registry to the correct Windows codepage.NLS_LANG="AMERICAN_AMERICA.WE8MSWIN1252"But why doesn't it work inside the command line console? Apparently because it used a different codepage. If you type chcp (requesting the codepage) at the DOS prompt, it would normally return 437 (it did on my machine). So you would need to enter`

set NLS_LANG=american_america.US8PC437 require 'oci8' OCI8.new('user','pw','db').exec('select * from emp') do |r| puts r.join('|'); end `in your irb and then all results would be displayed correctly. The crucial line being the correct setting of NLS_LANG. Wow! I got my results correctly in ruby! Now i was in the assumption that Rails would be a piece of cake, but that was wrong.

Fixing Rails

The easy idea would be to set NLS_LANG in Rails correct, before the oci8-library is required. My first approach was to set the NLS_LANG in the first line of the environment.rb with the following line:ENV["NLS_LANG"] = "AMERICAN_AMERICA.WE8MSWIN1252"But this didn't work. I am using NetBeans 6.5, and it took me a while to realise that if I edited a file to contain special characters (fixed text, e.g. on a menu) it would work. NetBeans (or Rails for that matter) standard works with UTF-8. So all files are encoded in that way. The easy solution would be to useENV["NLS_LANG"] = "AMERICAN_AMERICA.AL32UTF8"But that didn't work. I tried the alternative AMERICAN_AMERICA.UTF8 but that didn't work either. I am just guessing here, but i think somehow the NLS_LANG setting didn't get picked up in the Rails environment. It kept using the registry setting. So I tried to turn it around: make Rails use the windows codepage instead of utf-8. This took several steps:

  • change the default setting inside NetBeans to use the correct code-page instead of UTF-8. This in fact only affects the format of the files that are saved, but it is nevertheless important that all files being served are in the same format. Also convert all previously edited files from UTF-8 to standard ASCII. I used an editor to do that.

  • added the following to application_controller.rb:` before_filter :headers_iso

    def headers_iso

    make sure the charset matches the default Oracle NLS setting

    headers["content-type"]= "text/html; charset=windows-1252" end `

  • added the correct META-tag to application.rhtml in the HEAD-section:``Note: this meta-tag is not really needed, it has no real effect. And that finally worked! :)