February, 2009


21
Feb 09

Check if a file exists in Rails

Recently I was porting a legacy PHP application to Rails. One of the primary tasks was to resize a bunch of images. Below you can see what one of the database rows looks like.

mysql> SELECT id, filename FROM old_posts
+----+---------------------------------------+
| id | filename                              |
+----+---------------------------------------+
|  1 | unxplained-photo-1225258423-85706.jpg |
+----+---------------------------------------+
1 row in set (0.00 sec)                                                                  

mysql>

You’ll see that the name of the filename is stored in the database, the problem I encountered was that often times the actual file didn’t exist even though the record remained in the database.

Rails would get angry at me when I tried to resize an non-existent file. To account for this, I did the following:

if FileTest.exists?(filename)
 # some code here to
 # resize the image
end

For more information on this handy ruby module pop into the docs.


20
Feb 09

Rails’ symbols: don’t create them dynamically!

Symbols are great, we use them in hashes all the time…but did you know, symbols aren’t part of Rails’ garbage collection? When you create them, the memory the use has been allocated permanently! Why is this bad? So if we create a handful of symobls…no biggie, but what if we’re dynamically creating lots and lots of them? Major faux pas!

This was brought to my attention last night when I was trying to create a hash with some dynamic symbols. See below:

## here is some data

>> hardware = Hardware.find(:all, :limit => 2)
=> [#<Hardware id: 1, name: "Bolts", description: "Lorem ipsum dolor sit amet, consectetur adipisicing...", photo_front_file_name: "144_replica_wheels_Closeout_30_percent_off_prices_l...", photo_front_content_type: "image/jpeg", photo_front_file_size: 80842, photo_angle_file_name: nil, photo_angle_content_type: nil, photo_angle_file_size: nil, created_at: "2009-02-19 11:04:48", updated_at: "2009-02-20 20:29:46">, #<Hardware id: 2, name: "Nuts", description: "Lorem ipsum dolor sit amet, consectetur adipisicing...", photo_front_file_name: nil, photo_front_content_type: nil, photo_front_file_size: nil, photo_angle_file_name: nil, photo_angle_content_type: nil, photo_angle_file_size: nil, created_at: "2009-02-19 11:04:48", updated_at: "2009-02-20 07:18:32">]
>> y hardware.first
--- !ruby/object:Hardware
attributes:
  name: Bolts
  updated_at: 2009-02-20 20:29:46
  photo_angle_file_size:
  photo_front_file_name: 144_replica_wheels_Closeout_30_percent_off_prices_listed_.jpg
  photo_front_file_size: "80842"
  id: "1"
  description: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in recodehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  photo_angle_content_type:
  photo_front_content_type: image/jpeg
  created_at: 2009-02-19 11:04:48
  photo_angle_file_name:
attributes_cache: {}

=> nil
## don't do this
for hardware_item in hardware
 formatted[:#{hardware_item.name.downcase}] = hardware_item.description
end

>> formatted[:bolts]
=> "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in recodehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

## this is better
for hardware_item in hardware
 formatted[hardware_item.name.downcase] = hardware_item.description
end

>> formatted['bolts']
=> "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in recodehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

19
Feb 09

rake db:migrate for production databases

After I updated one of my applications that I’ve been working on, I kept running into an internal server error. I looked at the logs and for some reason none of my SQL queries were working.

Looks like I ran “rake db:migrate” and migrated the development database…not the production one. I scratched my head trying to remember the command. Here it is!”

rake db:migrate RAILS_ENV=”production”

18
Feb 09

All Rails crash course tutorials are available on GitHub!

ZIP files are silly :)

I’ve created a GitHub repository for all the tutorials to date and plan on using GitHub to version control all future applications. I will be editing the posts and removing any old download links shortly.

The repository is located at:
http://github.com/ng/crashcourse/tree/master

Want to check out the code? Run this in terminal:

git clone git://github.com/ng/crashcourse.git

Don’t have git installed? If you’re on OSX it’s simple!
http://code.google.com/p/git-osx-installer/


17
Feb 09

Paperclip doesn’t accept multiple files in Rails 2.3

Those of you who have upgraded to Rails 2.3 may have encountered a bug where Thoughtbot’s Paperclip doesn’t want to accept multiple file attachments. I checked my models, migrations, and forms but I couldn’t figure it out for the life of me.

It turns out there is some kind of bug with the Rack interface that is wonky in 2.3. By updating to edge Rails I was able to fix this little bug.


17
Feb 09

MySQL gem on OSX Leopard 10.5.x

I started to play with Rails 2.3 and ran into a little issue trying to access my database. I guess I shouldn’t have been ignoring all those decodeciation warnings…oops. Naturally, the first thing I did was run “sudo gem install mysql” which threw the following error:

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

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb install 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... no
checking for mysql_query() in -lmysqlclient... no

Gem files will remain installed in /Library/Ruby/Gems/1.8/gems/mysql-2.7 for inspection.
Results logged to /Library/Ruby/Gems/1.8/gems/mysql-2.7/gem_make.out

After digging around, I found the following command:

sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
Building native extensions.  This could take a while...
Successfully installed mysql-2.7
1 gem installed

Looks like it was successful…but wait, let’s check. Pop into IRB:

>> require 'mysql'
LoadError: dlopen(/Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle, 9): Library not loaded: /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib
  Referenced from: /Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
  Reason: image not found - /Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
  from /Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:36:in `require'
  from (irb):1

Further searching revelaed the solution:

sudo install_name_tool -change /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib /usr/local/mysql/lib/libmysqlclient.15.dylib /Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle

16
Feb 09

adapter: mysql (ArgumentError)

I was up late working on a project and I kept running into this error after I tried to deploy to my staging server. It turns out you can’t use tabs in a YAML file. Oops..after I removed the tabs and used spaces my app started successfully.

/usr/lib64/ruby/1.8/yaml.rb:133:in `load': syntax error on line 18, col 3: `   adapter: mysql' (ArgumentError)
  from /usr/lib64/ruby/1.8/yaml.rb:133:in `load'

  from /usr/lib64/ruby/gems/1.8/gems/rails-2.1.2/lib/initializer.rb:716:in `database_configuration'
  from /usr/lib64/ruby/gems/1.8/gems/rails-2.1.2/lib/initializer.rb:340:in `
initialize_database'
  from /usr/lib64/ruby/gems/1.8/gems/rails-2.1.2/lib/initializer.rb:124:in `process'

  from /usr/lib64/ruby/gems/1.8/gems/rails-2.1.2/lib/initializer.rb:97:in `send'
  from /usr/lib64/ruby/gems/1.8/gems/rails-2.1.2/lib/initializer.rb:97:in `
run'