ActiveRecord strict mode

I really like ruby and rails, but I find it frustrating as a lone developer.

The main path for Ruby / Rails seems to be very well documented. However, the second I get off the main path, which it seems everyone must do, especially someone who is upgrading an app that started as a rails 2.1.0 application, the documentation is scarce. I find I wind up having to search in source code more often than not to understand what’s going on. And that’s scary.

Case in point, I recently upgraded from rails 3.2 to rails 4.0. They implemented a major change with ActiveRecords that I can find no mention of any where except in the source and change log.

* `mysql` and `mysql2` connections will set `SQL_MODE=STRICT_ALL_TABLES` by
default to avoid silent data loss. This can be disabled by specifying
`strict: false` in your `database.yml`.

This is a good thing. For years i have been silently losing data. Data I don’t care about, but still, since it’s silently loss, I didn’t know.

However, after upgrading the app, fixing all the deprecation warnings, and ensuring all my test passed, I pushed the code to production. Then I started getting errors like:

An ActiveRecord::StatementInvalid occurred in items#search:

Mysql2::Error: Data too long for column ‘name’ at row 1…. (with lots of boring mysql)

Basically, my name field, at 256 characters was not long enough for some data. The error message made it clear what was happening, but I didn’t understand why they would make this type of change, without documenting it in the migration documents. Maybe they could have gone through a deprecation phase where it warned you first, before going from silent to exception?

It wasn’t until after I had fixed my code to either have the proper field lengths, or manually truncate the data myself that I found that a simple “strict: false” in my database.yml file would have returned to the old behavior while I tracked down the problem, or properly checked for it, so I wouldn’t get a server error.

Another more deadly example, one that took me over a month to track down was back in rails 3.1 when they changed the meanings of .dup and .clone.

ActiveRecord::Base#dup and ActiveRecord::Base#clone semantics have changed to closer match normal Ruby dup and clone semantics.
What this really meant to me was, everywhere I was using .clone, I needed to change to .dup. I was having object rot because when It thought I was cloning an item to make a new one, I was changing the original. I needed to .dup it, so I would not copy the id at the time of duplication. Basically, for what I needed, .dup and .clone changed names. This happened silently without warning or being highlighted in the upgrade documentation.

Installing Node.js on Debian

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

An old version of Node.js is available in official repo for Debian Sid(unstable).

To build a package and install it on Debian (as root):

apt-get install python g++ make checkinstall
mkdir ~/src && cd $_
wget -N http://nodejs.org/dist/node-latest.tar.gz
tar xzvf node-latest.tar.gz && cd node-v*
./configure
checkinstall #(remove the "v" in front of the version number in the dialog)
dpkg -i node_*

To uninstall:

dpkg -r node

MySQL Database Backup and Restore

To backup or restore a MySQL database, use the following commands:

Backup:

# mysqldump -u db_user -p[password] [database_name] > dump_file.sql 

Restore:

# mysql -u db_user -p[password] [database_name] < dump_file.sql

The dump_file.sql file will include all the information necessary to drop and re-create any table contained therein. However, if you are using this dump / restore mechanism to keep a development database in a “as needed” sync with production, it would probably be best to add a step of entering into mysql and dropping / recreating the database. This is because the dump file will not remove any tables in your schema that are not contained in the dump file.

# mysql -u db_user -p
> drop database database_name
> create database database_name

Git: Push to Remote Branch

The push command has the form of

git push remote_name source_ref:destination_ref

 Example:

git push origin +branch42:branch42

The plus is optional and allows non-fast-forward updates.

Alternate syntax is

git push -f origin branch42

if you omit the destination, it’s implied that it’s the same name. If tracking is set up to a particular branch on the remote it will go to that one. The -f is –force.

Deleting branches has 2 syntaxes, the old:

git push -f origin :branch42

and

git push --delete origin branch42

The first is read as “push nothing into branch42” which deletes it.

One trick is that if you specify . as the remote name, it implies the current repo as the remote. This can be used for updating a local branch without having to check it out:

git push . origin/master:master

will update master without having to checkout master.

git: revert (reset) a single file

I’ve made the leap from subversion to git.  I really like git, but there are a few things that confused me.  One is how to (in svn terms) revert an uncommitted file back to the latest version of the file under source control.

git checkout filename

This will checkout the file from HEAD of the current branch, overwriting your changed file.  Since this is the same command used to checkout branches, if you have a file with the same name as a branch you have to make a slight change.

git checkout -- filename

You can also pull files from any location in your repository like this.  man git-checkout for all the details.

git checkout [<tree-ish>] -- [<paths>...]

If you need to revert (reset) all your uncommitted work, the command is

git reset --hard

factory_girl_rails and ruby 1.8.7

factory_girl_rails gem requires factory_girl gem, which starting at 3.0.0 requires ruby 1.9.2. The Last factory_girl_rails version that works with ruby 1.8.7 is 1.7.0, which uses factory_girl 2.6.4

In Gemfile:

gem 'factory_girl_rails', '~> 1.7.0'

Moving from Drupal to Worpdress

Last week I needed to upgrade a couple of items on my server which caused a cascading effect of upgrades.  In the end, one of the sub-systems (Gallery 2) I depended on to provide photo galleries for www.adineswatercolors.com stopped working due to incompatibilities with modern PHP.   That left me with a few choices.

  • Ignore it and stop having galleries — Not really an option as Adine depends on the photo galleries.
  • Find some other old Drupal plugin compatible with drupal 6.xx to replace gallery 2 — Also did not seem to be worth the effort as Drupal 6.xx is close to end of life.
  • Upgrade to Drupal 7.xx — Seemed like the obvious first thought.
  • Move to WordPress 3.xx — No. Say it’s not so.

In reality, only the last two options seem viable.  Upgrade to Drupal 7.xx or move to WordPress 3.xx.

At first I really wanted to stay with Drupal, mostly because I started using Drupal years ago in the 5.xx days.  Back then I attended multiple Drupal conferences, user groups, and even helped organize the South West Drupal Summit.  But I’ve been out of the Drupal scene for a couple of years due to spending time with Rails, iOS, and Roller Derby.  The steep Drupal learning curve was back.  It was not obvious to me which modules were required, suggested, or even well accepted.

After spending several hours on the project, I decided to look at WordPress (multi-site) to see if it would be easier to create basic sites for Adine and I.  I was surprised at how easy it was to get WordPress to do what I was wanting to do.  The best part, it took almost no effort to get WordPress to hook into flickr so Adine only has one place to manage her images.  

While I’m  convinced there is much more power under the Drupal engine, I don’t think I will be needing to make use of that power.  And with less power comes and an easier to use system.  I am looking forward to teaching Adine how to update her content via the wordpress, something she never got a handle of with Drupal.

Connecting to a Crashplan instance in the Cloud

Crashplan is a great “free” utility to automate the backing up of all your systems. I have been using it for almost a year to backup all my computers including my cloud instances.

I had to perform some maintenance on one of my cloud computers and forgot how to connect the admin tool to it. Below I’m outlining the steps so I won’t forget again.

* Create a ssh tunnel to the machine

ssh -L 4200:localhost:4243 host

* Updated local CrashPlanDesktop to use port 4200

vi /usr/local/crashplan/conf/ui.properties (change port to 4200)

* Run CrashPlanDesktop

/usr/local/bin/CrashPlanDesktop

* Don’t forget to revert the changes to the configuration file

vi /usr/local/crashplan/conf/ui.properties (change port back to 4243)

 

Empty Postfix Mail Queue

Had an issue today where a bug sent over 20,000 messages into my postfix mail queue. Google then started “rate” limiting me as this issue was basically a DOS attack on my mail box. After some research, I found a couple ways to empty the postfix mail queue.

If you only want to purge the queue of email from use user, as root try:

mailq | tail +2 | grep -v ‘^ *(‘ | awk ‘BEGIN { RS = “” } { if ($8 == “user@example.com” && $9 == “”) print $1 } ‘ | tr -d ‘*!’ | postsuper -d –
To purge the entire queue:

postsuper -d ALL