has_many tricky replace method

Today I discovered a small bug / feature of rails 3.1.3.

Having the following structure:

class Item < ActiveRecord::Base
  has_many :tags
end

class Tag < ActiveRecord::Base
  # Tag has a boolean flag 'enabled'
  belongs_to :item
end

It's possible to completely replace the has_many collection
with a new collection. Make this collection:

item = Item.find(1)
tags = [ 
  item.tags.create( :enabled => true, :name => "tag1" )
]

All fine for the moment. As expected the enabled flag of the first item is set:

tags[0].name      # => "tag1"
tags[0].enabled?  # => true

Now replacing the existing tags:

item.tags.replace( tags )
item.tags[0].name        # => "tag1"
item.tags[0].enabled?    # => false 

What?? It just forgot the enabled flag!!

The way to replace the items is by assigning:

item.tags = tags
item.tags[0].name        # => "tag1"
item.tags[0].enabled?    # => true

So remember when replacing collections of has_many do not replace them but assign them....

Slow response testing localhost sites in Google Chrome on Mac OS X

Last week I noticed the response of localhost requests were slow in Google Chrome, but responded very quickly in Safari. I suspected Chrome was submitting my local requests to it's data hunger servers to build an even better profile of me.
I tweaked a lot of Chrome settings so everything would be kept private, but no success. After several attempts I found the problem:

To test multiple sites and testing multi-domain rails applications I've changed my /etc/hosts file to contain the following items.

127.0.0.1 nice-domain.local 
127.0.0.1 nice.sub-domain.local
127.0.0.1 gamecreatures.local

So calling: "gamecreatures.local" in Chrome causes a too long delay for showing something..
calling "gamecreatures.local" in Safari responded instantly..

After doing some research, I've learned Apple is doing something special with the .local postfix. It is used by the Bonjour services somehow. I don't know exactly what, but they do...

So changing all the extension from ".local" to something else for example ".loc" solved the issue for me:

127.0.0.1 nice-domain.loc
127.0.0.1 nice.sub-domain.loc
127.0.0.1 gamecreatures.loc

Now Chrome also responds instantly...
Sorry Google for "assuming" you trying to steal all data from me... (Or should I use the _nomap extension for this one too ?!?)

Rails 3.1 Assets Precompilation

Today I tried to 'release' our rails 3.1 product to the production environment. Which of course has precompiled assets.

The app deployed nicely. But when I tried to start the app, I've got the following error:

ActionView::Template::Error (locales/nl.js isn't precompiled): 
...

Deploying the app with capistrano (which precompiles my assets) did not compile my javascript-locales.

The cause of this seeems to the that the assets pipeline precompilation task, only precompiles the application.js file...

To add extra files for precompilation, place the following code in your config/application.rb:

    config.assets.precompile << "locales/*.js"  
    config.assets.precompile += %w(rails_admin/rails_admin.js rails_admin/rails_admin.css)

This examples precompiles ALL my locale files in the app/assets/locales/* directory.

And as a bonus it also compiles the assets of the the rails_admin plugin.

Ruby on Rails / ChiliProject encoding issues

This week I've decided to exchange Redmine for the ChiliProject. The reason for this is the support for Ruby 1.9. My Apache Passenger server runs Ruby 1.9 so for Redmine I needed a seperate webserver.

When I tried to access the "My Account" page I recieved the following error:

ArgumentError (invalid byte sequence in US-ASCII):
  <internal:prelude>:10:in `synchronize'
  passenger (3.0.7) lib/phusion_passenger/rack/request_handler.rb:96:in `process_request'
  passenger (3.0.7) lib/phusion_passenger/abstract_request_handler.rb:513:in `accept_and_process_next_request'
  passenger (3.0.7) lib/phusion_passenger/abstract_request_handler.rb:274:in `main_loop'
  passenger (3.0.7) ...
`handle_spawn_application'
  passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop'
  passenger (3.0.7) lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously'
  passenger (3.0.7) helper-scripts/passenger-spawn-server:99:in `<main>'

Rendering /data/www/rails/chili/public/500.html (500 Internal Server Error)

Solution

How should I solve this? The chiliproject has an issue related to this: https://www.chiliproject.org/issues/591.

The following Apache configuration fixed the issue: (The sample is on a FreeBSD system)

I added the following code to a file in the /usr/local/apache22/envvars.d/environment.env

export LC_CTYPE="en_US.UTF-8"

Problems I ruled out or fixed

While trying I also made sure the following things were configured:

I made sure the database is UTF-8. I re-created the database
an ran the migrations again.

create database chiliproject character set utf8;

I used the mysql2 connector instead of the mysql connector in database.yml

Running Ruby on Rails 3.1 on FreeBSD

Are you trying to install / run Rails 3.1 on a FreeBSD system...?
You will probably get errors of a missing javascript engine.

You should try to install node and google V8 as javascript engine

cd /usr/ports/lang/v8
make install clean
cd /usr/ports/www/node
make install clean

Now it should work :-)