I don’t get form_tag

Ok, so I call something like

html_options = {
  :onSubmit => "new Ajax.Request(\\\"/barn/render_event_response\\\")"
}
 
form_tag("barn", html_options)

Can you see my well-escaped JavaScript?

However, I get

"<form action=\"/barn/render_event_response\" method=\"post\" 
  onsubmit=\"new Ajax.Request(\\&quot;/barn/render_event_response\\&quot;)\"

Why does Rails &quot; my JavaScript? Can anybody help?

Releasing with Jeweler

I love jeweler for releasing my gems, however I tend to forget how it is working, so here’s my release workflow.

1. Bump and Commit

Bump the version (usually in lib/a_perfect_gem/version.rb) and git commit my latest changes

2. Doublecheck

git status to check if my working tree is clean

git status
# On branch master
nothing to commit (working directory clean)

Otherwise jeweler will complain

$ rake release
rake aborted!
Hey buddy, try committing them files first

3. Release

Finally do

$ rake release

which will

  • tag the commit with "v#{A_PERFECT_GEM::VERSION}"
  • push the commit(s) to origin
  • push the tag to origin
  • build the gem
  • push the gem to gemcutter

Props to [technicalpickles].

The cool thing is that Rails’ script/generator script can be invoked via an API call

Rails::Generator::Scripts::Generate.new.run(%w(controller blog), :destination => '/tmp')

so you can create assets in your code, or test the generator.

Where is my JavascriptGenerator?

The bad thing is, that after you used Rails::Generator, you can’t rely on autoloading anymore, at least for classes ending with Generator.

When trying to use my own class JavascriptGenerator (which has nothing to do with Rails at all) I got

JavascriptGenerator::Base.new # NO rails...

Rails::Generator::GeneratorError: Couldn't find 'javascript' generator

which is really annoying. That’s Rails “magic” again (somewhere in rails/generator/…):

class Object
  class << self
    def lookup_missing_generator(class_id)
      if md = /(.+)Generator$/.match(class_id.to_s)
        name = md.captures.first.demodulize.underscore
        Rails::Generator::Base.lookup(name).klass
      else
        const_missing_before_generators(class_id)
      end
    end
 
    unless respond_to?(:const_missing_before_generators)
      alias_method :const_missing_before_generators, :const_missing
      alias_method :const_missing, :lookup_missing_generator
    end
  end
end

That’s a typical example how Rails assumes things automatically that you don’t expect.

I personally think that extending Object should be allowed to non-magicians only.

It’s finally time to try out things with Ruby 1.9 - people start complaining that my libs don’t run with 1.9. Sorry for that. I’m still sticking to “Never touch a running system!”, so why should I use Ruby 1.9 when 1.8 works great?

RVM

First I discovered rvm which is a great tool for hosting different Ruby versions in your shell and switching environments on the fly.

That’s

> sudo gem install rvm

Now go and install Ruby 1.9.1 (couldn’t get 1.9.2 working)

> rvm install 1.9.1

This will install Ruby 1.9.1 in your home directory, which is awesomely cool.

Switching to the new ruby/gems is nothing more than

> rvm use 1.9.1

Running Rails

Things start getting shitty now. When trying to run Rails with ruby 1.9 I got something

no such file to load -- openssl

rvm explains to install the package openssl. That doesn’t work for me

$ rvm package install openssl
Package 'openssl' is unknown.
Usage: 'rvm package {install,uninstall} {openssl,zlib,readline,iconv,ncurses}'

which is… strange.


Note: Wayne fixed that in the rvm release 0.1.24 - so the rest of this article is useless. Thanks, cowboy!


Following the great directions here didn’t help either, although it’s a good post.

At some point make failed with

error: ruby/io.h: No such file or directory

The solution

I finally ended up fixing it with

$ sudo apt-get install libopenssl-ruby1.9.1
$ cp /usr/lib/ruby/1.9.1/i486-linux/openssl.so ~/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux/
$ cp -R /usr/lib/ruby/1.9.1/openssl* ~/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/

and the shit’s working.

Installing gems

rvm provides some decent way to install gems, it works like

$ rvm 1.9.2 gem install cells --no-ri --no-rdoc

When running ruby 1.8.7 be sure to install sqlite3-ruby, not sqlite3. The latter version is only for 1.9 and will throw arbitrary

NameError: uninitialized constant Encoding

Hope that helps!

When a friend tried to upload some files via Skype to my PC it kept failing, Skype 2.1.0.47 for Ubuntu complained “can’t write to file” as soon as I accepted the upload.

Here’s the solution:

First, I created a world-writable directory

mkdir /home/nick/skype-uploads
chmod 777 /home/nick/skype-uploads

I opened the File Transfer dialog, clicked the sprocked icon and selected Change Default Download Directory.... After setting that directory to my fresh skype-uploads dir uploads worked!

After copying a presentation from my laptop to my desktop box (which’s running OpenOffice.org 3.1.1) the embedded AVI videos didn’t show up anymore. It turned out that the JRE was missing gstreamer.

The solution

sudo apt-get install ubuntu-restricted-extras

I recently had to port a very old perl project to a new server, which is running mod_perl- that made me some headache as I didn’t know anything about that environment.

Pages with dynamic form input from CGI::param suddenly seemed to be “cached”, the script did process old variables and emitted wrong output. After diggin’ into mod_perl with this great article the solution was quite easy.

mod_perl somehow keeps a persistent process environment, thus restoring variables declared with my. As I didn’t want to rewrite the whole thing I simply changed lines like

my $type = param("type");

to

local $type = param("type");

and everything works fine and “uncached”. I know there are several pitfalls with local again, anyway, I’m not into mod_perl, things seem to work and a 10-years old medieval project’s running again.

Colleagues keep laughing at me.
It seems that I missed the point in a programmer’s life where he faces a shimmering light at the end of the dark terminal tunnel, where he suddently gets enlightened… and switches to eclipse or Textmate.

Being an IDE-reject I’m used to work with bare-bones text editors, which support syntax-coloring, a bright background and a few well-established keyboard shortcuts like Cmd+c Cmd+v.

That’s all I need.

Ever since I can remember I disliked IDEs and how they suppressed my way of organizing files, tools and minds. And they are slow.

The last 4 years I worked with nedit and my own small file-browser kebap. Two weeks ago me and my colleague Felix discovered scribes, a text-editor for Linux written in Python. Dozens of text-editor came and went away in my life, but for some reasons I really like scribes. Some of its key features I already love are

  • streamlined workflows with a simple and clean UI
  • jump to files with the F9 file-dialog by typing their name
  • code templates which can be triggered while typing
  • character pair completion -yeah i hate to close a bracket and move back the cursor by hand
  • word completion while typing remembers phrases you typed, like long function names and cryptic variables
  • sufficient syntax-coloring for Ruby and PHP (well that could be better)

I really was distracted by the tab-less UI first. “What a mess!” came to my mind. A couple of days later I was conviced that the arrogant attitude of scribes is… cool.
It’s useless to organize your docs in tabs, the more docs you open, the sooner you forget which tabpanel holds the code file you’re looking for. So why not let the F9 file browser keep track of all those files?

Today I noticed that I had 46 opened scribes documents - each in a separate window - while programming at work. Since I simply hit F9 and type in a few characters to jump to the file I completely forgot the “need” for MDIs, tabs, project managers and other “tools”.

Enough praising, let’s hit the keyboard.

Installing scribes 0.4-dev on Ubuntu Jaunty

The 0.3 version shipped with Ubuntu has some bugs, so I recommend the 0.4 version which is almost stable.

sudo apt-get install bzr libglib2.0-dev gnome-common
bzr branch lp:scribes
cd scribes/
./autogen.sh
make
sudo make install

When starting scribes in a terminal, you might get a python exception bitching about
ImportError: No module named gtksourceview2

Well, just do

sudo apt-get install python-gtksourceview2 python-gnome2-desktop-dev python-gnome2-extras-dev

and have fun experiencing a smart, but not too smart editor. Thanks, mystilleef!

After more than a year of marriage my X31 laptop and gutsy had to break up again. I had to upgrade my linux distribution due to some very old, outdated packages. As usual: problems after upgrading. Did I notice that I really hate to upgrade things?
Well, here are some directions which should ease your jump to intrepid.

My current kernel: 2.6.27-11-generic.

Hibernate and suspend

One reason I sticked to gutsy was a working hibernate/suspend setup. With intrepid

  • booting for resume crashed after suspend (black screen)
  • hibernation crashed and left a blinking caps lock LED

Well I found out this was my PCMCIA WiFi card- a D-Link DWL-G630. If unplugged, suspend and hibernate seemed to work. All you need to do to fix it is configuring gnome-power-manager correctly (which is the default Ubuntu hibernation subsystem). It needs to unload the kernel module for the WiFi card.

Create the file /etc/pm/config.d/modules if it does not exist already and fill in the line

SUSPEND_MODULES="rt61pci"

Wireless and WPA2 encryption

Ok, so don’t waste your time trying to log into a WPA2 encrypted wireless network with the built-in Cisco Aironet Wireless 802.11b. The airo driver in the current kernel only supports WEP. That sucks. Go and get that D-Link card, it works great.
Anyway, the Aironet still is enabled and sometimes confuses network-manager.

Besides, it is completely nonsense to have two active antennas next to your balls, so switch off the built-in.

The Fn+F5 key doesn’t turn off the beast. We have to use the force again. Instruct modprobe to no longer load the kernel module by editing /etc/modprobe.d/blacklist and add the line

blacklist airo

Flash for Firefox

Even the Flash installation is nothing more than

sudo apt-get install flashplugin-nonfree

Don’t forget to restart your browser- now you can watch p… eeeer play free flash games again.

Ruby on Rails

Install the ruby interpreter and necessary tools with

sudo apt-get install ruby1.8 ruby1.8-dev memcached 
  libopenssl-ruby1.8 libmysqlclient15-dev

but do not install gem using apt-get since it will mess up things. Browse to http://rubyforge.org/frs/?group_id=126 and get the newest rubygems package, unpack it and install it with

cd rubygems-1.3.1
sudo setup.rb
sudo mv /usr/bin/gem1.8 /usr/bin/gem

Then install necessary gems

sudo gem install rake rdoc memcache-client system_timer 
  rails mysql

Ok, Ubuntu rocks again

Retrospectively I have to admit this was the easiest upgrade ever. I could manage the hibernate issue quite quickly (with some help of my buddy Felix). Everything else worked out-of-the-box. Big props and thanks to the (X)ubuntu team!

If you’ve never heard of pingbacks before, you’re out. Go home.

Ok, pingbacks are this mysterical feature when you write on your blog A and refer to some article on blog B. After you publish your article on blog A, something happens behind the curtain. Suddenly there’s a new comment on the blog B article you cited in your text, and this comment links back to your article on your blog A. That’s called a pingback.

Whereas sending a pingback is just a modest effort by fireing some small XML-RPC request, receiving is quite a bunch of work. A pingback’able site needs to

  • provide an XML-RPC capable server to receive pings
  • check the refering site’s article for the link to us
  • excerpt a piece of content from this refering article on blog A
  • store the extracted content with the link on the pinged page, maybe as a comment

Fortunately, there’s already a Rails plugin to handle this tedious task, namely pingback_engine which I wrote as a christmas gift for my friends on the net.

Receiving Pingbacks with pingback_engine

To make our Rails app pingback’able we need to install the engine, setup the server url propagation and then hook in a method for processing incoming pings. That is awesomely easy.

Installation

Inside the rails app directory install the engine, and a needed gem.

script/plugin install git://github.com/apotonick/pingback_engine.git
gem install hpricot

Your Rails app is now capable of receiving pingbacks via XML-RPC.

Propagating the server for auto-discovery

However, if a blog links to you, this blog will usually scan your page to discover the XML-RPC pingback server. What a pingback’able page should do to propagate this url is described in the pingback specification.

It roughly says, to define a pingback-enabled page

  • either return a X-Pingback HTTP header
  • or provide a special link element in the page HTML header
  • or do both!

In our example, we’re on the safe side by providing both. I instruct my blog controller to send an X-Pingback header by calling set_xpingback_header in the action that shows my articles.

# file: app/controllers/blog_controller.rb
 
class BlogController
    include PingbackHelper
    helper :pingback
 
    def article
      set_xpingback_header
      # ...

This will send the respective header with the correct url as soon as some blog tries to auto-discover the address for your XML-RPC pingback server.

Additionally, we provide a special <link ..> element in our application layout so the XML-RPC address is visible everywhere in the app.

# file: app/views/layouts/application.html.erb
 
      ...
      <%= pingback_link_tag %>

Now other blogs will find your pingback server if some article links to your site.

Processing an incoming pingback
The only thing we have to implement is the pingback processing method. It’s currently put at the bottom of the rails environment file. Of course I could just delegate to another class method in some model, but for demonstration purpose it’s all in one file.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# file: config/environment.rb.
 
# ...
Pingback.save_callback do |ping|
    comment = ArticleComment.new
    comment.author     = ping.title
    comment.author_url = ping.source_uri
    comment.text       = ping.content
    comment.created_at = ping.time
 
    referenced_article = Article.find_by_url(ping.target_uri)
 
    if referenced_article
      comment.article_id = referenced_article.id
      comment.save
 
      ping.reply_ok # report success.
    else
      # report error:
      ping.reply_target_uri_does_not_accept_posts
    end
  end

Easy. Into the block to Pingback.save_callback we get a ping instance, which is enough to process, check and store the incoming pingback.
I just

  • create an ArticleComment instance, which is an ActiveRecord-derived class and represents comments in my blog (line 22)
  • assign -or map- values from ping to the comment
  • check the ping if it really points to an article in my blog
  • decide the incoming ping is invalid and discard it (line 37)
  • or save the comment in my blog and report success (line 34)

Anyway, all we have to do now is to login to some blog (recent Wordpress blogs work great) and publish an article that links to a pingback’able page on our Rails site. The blog will send us all the information we need to receive the ping, and the pingback_engine will almost do the rest!

Testing manually
For debugging or testing purposes you can also use a test script shipped with the plugin. All you need is your set up rails site and a HTML page accessable on some webserver. The HTML page must link to a pingback-enabled page on your rails site.

By firing

pingback_engine $> script/send_pingback.rb http://site.com/page_linking_to_us.html http://my.rails.site.com/article-31

you can issue an XML-RPC pingback on the local server and debug things.

However, it should all work as it is shipped, so have fun when making your Rails site pingback’able!