Validation gotcha (before_save not being called)

October 18th, 2010 by e-thang No comments »

So once I figured it out, there was a generous *facepalm*. Nonetheless, in case you’re struggling with the same problem, here it goes.

I had a before_validation callback on an ActiveRecord model. I was running in test mode using Shoulda and FactoryGirl, so I figured those 2 gems had something to do with it. Then came the humble pie.

I also had a validates_presence_of on the model, and it was getting called before the before_validation callback. The test wasn’t setting that attribute, so naturally I never got to the callback.

Once again it was not a cloud if improbability that caused the universe to collapse around me. It was a bone-headed error.

Rails + WordPress (at the same time)

June 1st, 2010 by e-thang No comments »

It is a Sin to be a “Rails programmer” and not use a blogging engine you wrote yourself and especially in Rails, but there are cases when one’s available time is more important than one’s soul.

This particular case assumes you use shared hosting.  That’s probably another bad thing, but whatever.  Also, you need access to your public_html folder’s .htaccess file.  In fact, this whole setup is so host-specific that you might find it worthless.

Starting over.  Shared host.  public_html folder. Apache. Your host routes traffic to your app by rewriting your requests via a proxy to a specific port.

Now let’s say you have the domain www.domain.com.  Your host does something like:

RewriteCond %{HTTP_HOST} ^domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.domain.com$

RewriteRule ^(.*)$ "http\:\/\/127\.0\.0\.1\:12%{REQUEST_URI}" [P,QSA,L]

Note: port numbers have been changed to protect the innocent.

This basically just says “if a request hits me and the host matches your domain, I’m gong to proxy it on to myself on a different port.”  The webserver runs a request against itself on a different port, which presumably is picked up by whatever handles your Rails application.

Well, you want your blog to be at http://www.domain.com/blog.  That unfortunately does contain your domain in the HTTP_HOST.  Which means Rails will try to serve up your blog.  Which means it will fail or, if you actually have your blog in your app’s public folder, will serve up your .php files as raw text downloads.

Solution:

RewriteCond %{REQUEST_URI} !^/blog/(.*)$
RewriteCond %{HTTP_HOST} ^domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.domain.com$
RewriteRule ^(.*)$ "http\:\/\/127\.0\.0\.1\:12%{REQUEST_URI}" [P,QSA,L]

We add an additional condition to our rewrite requiring that the actual path requested (Apache’s REQUEST_URI expands to that) NOT match “/blog/” followed by pretty much anything.  This will get your webserver to handle all of these requests as if your Rails app weren’t there, which is what you’re going for anyway.

This isn’t limited to WordPress.  And note that whatever you are trying to run needs to be in your Apache DOCUMENT_ROOT folder.  That could be like “public_html” or something.  I don’t know the answer to that for you.  You CAN work around that with other directives, but that is beyond the scope of this entry.

When having trouble installing the mysql gem on OSX

April 21st, 2010 by e-thang No comments »

And you get an error like:

*** extconf.rb failed ***

Go read:

http://blog.bmn.name/2008/02/rails-gem-install-mysql-throws-error-extconfrb-failed

How to run OS X in one language but certain apps in another

April 20th, 2010 by e-thang 2 comments »

Ever want to run your OS in French but you live in America and type mostly in English?

http://www.tj-hd.co.uk/en-gb/languageswitcher/

Because if you want to use more than one language at a time on your computer you’re Doing It Wrong, because if you were doing it right, Apple would have provided a way to do it that way.

Astounding that this requires a 3rd-party application. Yes, it is possible to change the language in your document, but if you also use paragraph styles, they have a set languge.  And that set language doesn’t change when you set the language on the whole document.  And you can’t highlight the whole document of mixed languages and set the whole thing to one of them.  Usability at its finest.

Apple, some computer users do know how to operate computers.

Rails 2.3.5 doesn’t play well with Rack 1.1.0

February 16th, 2010 by e-thang No comments »

Ever get this gem when running a Rails 2.3.5 application with Thin?

/Users//config/../vendor/rails/railties/lib/initializer.rb:271:in `require_frameworks': can't activate rack (~> 1.0.1, runtime) for [], already activated rack-1.1.0 for ["thin-1.0.0"] (RuntimeError)
from /Users//config/../vendor/rails/railties/lib/initializer.rb:134:in `process'
from /Users//config/../vendor/rails/railties/lib/initializer.rb:113:in `send'
from /Users//config/../vendor/rails/railties/lib/initializer.rb:113:in `run'
from /Users//config/environment.rb:13
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from /Library/Ruby/Gems/1.8/gems/thin-1.0.0/lib/rack/adapter/rails.rb:31:in `load_application'
from /Library/Ruby/Gems/1.8/gems/thin-1.0.0/lib/rack/adapter/rails.rb:23:in `initialize'
... 6 levels...
from /Library/Ruby/Gems/1.8/gems/thin-1.0.0/lib/thin/runner.rb:139:in `run!'
from /Library/Ruby/Gems/1.8/gems/thin-1.0.0/bin/thin:6
from /usr/bin/thin:19:in `load'
from /usr/bin/thin:19

Disappointing to be sure, but there’s a simple fix I found here.  Thin will try to load the latest version of Rack that you have installed, but Rails specifically asks for 1.0.1.  You can’t have 2 versions of it running at the same time, so RubyGems pukes.

The simple solution is to uninstall Rack 1.1.0.  If that isn’t an option for you, dang.  There’s always this rails ticket you could go fix and make a big name for yourself in the community. ;)

How to freeze gems in Rails

February 1st, 2010 by e-thang No comments »

http://blog.logeek.fr/2008/12/23/how-to-freeze-gems-with-rails-2-1

Paperclip/ImageMagick/RMagick error: “is not recognized by the ‘identify’ command”

December 30th, 2009 by e-thang 4 comments »

If you’re using the above combination, and you’re getting the above error, make sure that you’ve configured Paperclip to find ImageMagick in the right place.  Create an initializer file, RAILS_ROOT/config/intializers/paperclip.rb, and put “Paperclip.options[:image_magick_path] = ‘path/to/image_magic’” inside of it.  On Mac or a *nix system, type “which identify” to find the right folder.

Big thanks to avit on this forum for the solution.

shoulda and factory_girl not cleaning up db between tests

December 22nd, 2009 by e-thang 4 comments »

Wow, this one was a doozy. I recently (yesterday) had my first introduction to shoulda and factory_girl for testing. I’m torn as to whether or not fixtures are the root of all evil, as I haven’t really encountered problems with them and find them very simple to use and maintain, but that isn’t the point of this post.

The point is that just starting a new job I figured a good thing to do was first run the unit tests to make sure I had set up the app properly. I was treated to many failures and investigated why. I found many failures caused by a polluted database. Previous tests weren’t cleaning up after themselves, so later tests had bad state (duplicate records and that sort of thing). While that may be a plug for database level enforcement of that kind of rule, that task was beyond the scope of what I was doing.

I scoured Google looking for answers, and a day later I finally found it. Just to stretch you along even further, here’s what it wasn’t:

  • shoulda not running implicit teardowns
  • transactional fixtures being turned off

No, it was a great deal dumber than that, and a thanks to Eric Artzt, whoever you are, for providing the solution. The table that was giving me fits is a MyISAM table, which doesn’t support transactions. Which means there are no rollbacks to clean up my DB state. Which means I either have to explicitly put calls to do that into an explicity-defined teardown method or switch the engine on the table in question.

Installing Ruby gems that require building native extensions on Snow Leopard

December 18th, 2009 by e-thang 2 comments »

I haven’t tested this on all “machines” running Snow Leopard, but on the brand new one I had to get today for work, I found that the default Ruby / Gems install doesn’t support installing gems that require building native extensions. The error message I was treated to contained the following:

MacBook-Pro-de-Ethan-Garofolo:~ juanpaco$ sudo gem install thin
Password:
Building native extensions. This could take a while...
ERROR: Error installing thin:
ERROR: Failed to build gem native extension.

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb install thin
mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/ruby.h


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

The solution was hyper-intuitive. Install XCode. Because of course that's the first thing you think of.

Renaming a database in Rails

December 14th, 2009 by e-thang No comments »

Hooray for a non-rant post!

The heart of this method works outside of Rails, but there’s one particular convenience method that Rails provides.  Find some way to mimic that behavior, and the rest would apply.  Also, this is a MySQL-specific solution.  I haven’t tried it with any other DB systems.

We “rename” a database by moving all of its tables into a new database.  We do so via MySQL’s RENAME TABLE command.  Basically, create an empty database with the new name.  We then use our ActiveRecord connection’s “tables” method to loop over all the tables in our database, executing a RENAME TABLE from the old to the new with each iteration. “Tables” is the convenience method I mentioned above. Encapsulating this in a method we get:

def rename_database(old_db_name, new_db_name)
    ActiveRecord::Base.connection.execute "CREATE DATABASE #{new_db_name}"
    ActiveRecord::Base.connection.tables.each do |table|
        ActiveRecord::Base.connection.execute
            "RENAME TABLE #{old_db_name}.#{table} TO #{new_db_name}.#{table}"
    end
    ActiveRecord::Base.connection.execute "DROP DATABASE #{old_db_name}"
end

Error checking is left as an (important!) exercise to the reader.  Also, you may prefer to monkey patch this into ActiveRecord itself as opposed to some odd method floating around in global space.

This presupposes that the new database destination will be on the same server.

Another way to rename a database is to mysqldump the old one to a file and then reimport it to the renamed database.  The method presented in this article is advantageous if your database has a large amount of data.  Renaming a table is almost instant.  Dumping millions of rows and reimporting them is not so instant.