Ruby on Rails

Tagmindr: Use del.icio.us to set web-page reminders

Posted in Ego, Infoglut, Ruby on Rails, Seattle on October 8th, 2007 by leodirac – 4 Comments

I spent Saturday hanging out with about a dozen hackers building Tagmindr: Remember the future.  Here’s the site’s self-description:

    Put any bookmark in a time capsule and we’ll send it to your future self.

    Give us your del.icio.us username and we’ll feed you anything that you’ve tagged as: "tagmindr" and "remind:YYYY-MM-DD". We’ll remind you via RSS, SMS, Email or IM, so long as it’s RSS.

    (SMS, Email and IM coming later.)

The use case is that you find a page about a product or service that you’d like to look at sometime later so you tag it into del.icio.us thinking you’ll get back to it, but of course you never will.  With Tagmindr you can set a specific date when it will pop up in your feed reader so you will remember to check it out again.

Brian Dorsey came up with the idea and gathered a bunch of us together at his house with the goal of building a web 2.0 app in 6 hours.  We spent an hour or two setting up our dev environments and talking over the goals of what we were going to do.  Then we did a skills inventory, and divided up into teams to start doing the work.  I worked on the back-end team which was a ton of fun.  The project is written using Django, an MVC-based web application framework for Python, which is conceptually quite similar to Rails.  It’s got a few things that are way cooler than rails and a few things that are definitely lacking.  From noon to 6pm we coded, while others did graphic design, HTML layout, and wrote copy.  I had to leave fairly promptly but at the time it seemed we had slipped just a bit — there were still a few issues rendering the design on the production server, and the back-end code still had a couple of bugs.  It seemed like another hour or two’s work total.

Thanks and props to all the wonderful people I met and got to work with.  Special thanks to Anders for holding my hand through basic Python and Django to a level of minor productivity.  I gotta say that Python is really clean.  Makes me realize how much Ruby can look like incomprehensible Perl.

Rails bug with assert_redirected_to causing NoMethodError: undefined method `first’

Posted in Ruby on Rails on October 7th, 2007 by leodirac – Be the first to comment

I’m posting about a bug I ran into recently in Rails.  It’s filed against the core team and being addressed, and documented on the forums, so this post might be unnecessary.  But the bug is bizarre and confusing enough that I thought I’d post a succinct summary of the problem and how to fix it.

If you have code in a controller that redirects to another page, say like this:

  def index    redirect_to :controller => :store  # WRONG!  end

This looks fine and actually runs fine too.  But there’s a problem if you try to test it — the tests will fail.  Consider this simple test case:

  def test_index    get :index    assert_response :redirect    assert_redirected_to :controller => 'store'  end

This test will fail with this unhelpful error message:

  1) Error:test_index(WidgetsControllerTest):NoMethodError: undefined method `first' for :store:Symbol    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/assertions/response_assertions.rb:72:in `assert_redirected_to'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/assertions/response_assertions.rb:43:in `each'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/assertions/response_assertions.rb:43:in `assert_redirected_to'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/assertions.rb:60:in `clean_backtrace'    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/assertions/response_assertions.rb:35:in `assert_redirected_to'    ./test/functional/widgets_controller_test.rb:21:in `test_index'

The problem is in that controller code.  Apparently (this was news to me) Ruby strings and symbols aren’t the same.  That is :store and ’store’ compile to different code.  If you change your controller to this:

  def index    # redirect_to :controller => :store  # WRONG!
    redirect_to :controller => 'store'   # Correct
  end

Not only will the code function properly, but it will pass the functional test too.  Hope this helps.

Facebook apps in Rails: Bug in rfacebook-0.6.4 – fbparams not set

Posted in Ruby on Rails on July 20th, 2007 by leodirac – 2 Comments

Like a number of other developers, I’ve been beating my head against a wall for the last couple of weeks trying to figure out how to set up a facebook app using ruby on rails.  I finally figured out at least one major problem I’ve been running into — the standard library for writing facebook apps in ruby, rfacebook, has a bug in its latest version 0.6.4.

I haven’t figured out exactly what’s wrong yet, but I’ve figured out how to avoid it.  If you’re getting this kind of error message:

You have a nil object when you didn't expect it!You might have expected an instance of Array.The error occurred while evaluating nil.length

The error might comes from a stack trace like this:

.../rfacebook-0.6.4/lib/facebook_rails_controller_extensions.rb:37:in `fbparams'
.../rfacebook-0.6.4/lib/facebook_rails_controller_extensions.rb:60:in `fbsession'
.../rfacebook-0.6.4/lib/facebook_rails_controller_extensions.rb:130:in `require_facebook_login'

Astute developers will open up the code and see that fbparams isn’t being properly initialized because of a simple blunder — calling a method on a potentially nil object before trying to initialize it.  But correcting this mistake won’t get your app to run.  There are other problems too.  The way to fix your app is to back down to rfacebook version 0.6.3:

gem uninstall rfacebook
gem install rfacebook -v 0.6.3

And don’t forget to clear your cookies and your session objects

rm tmp/sessions/*

This has certainly helped me.  I hope it helps you.

Model Security: Such a good idea

Posted in Electronic Security, Ruby on Rails, Software Engineering on May 9th, 2007 by leodirac – 2 Comments

Why it’s good to break the MVC pattern

Bruce Perens hit on a really good thing when he wrote a package for Ruby on Rails called Model Security.  It’s too bad the project is gathering dust.  But even if you don’t use the whole thing (I haven’t been able to) there are some really valuable ideas and chunks of code in there.

The idea behind Model Security is to centralize security rules in the model classes.  Certain objects can only be accessed by certain users.  Perens talks about multi-layered security.  But in my mind the real benefit is that you can just write the basic rules in one place and not worry about it everywhere else.

An apparent problem with this strategy is that it violates the encapsulation of the MVC pattern.  The only way to put security into the Model part of the pattern is for the Model to know who is trying to access it.  The concept of the user is generally localized to the controllers in an MVC pattern.  Maybe the view.  But definitely not the model.  In MVC, the model is supposed to stand entirely on its own and not depend on anything except maybe the persistence mechanism (i.e. the database).  So in this way Model Security violates the basic MVC pattern.  Violating well-known design patterns is bad, right?

Absolutely not!  In this case it’s actually a really good thing.  Developers who blindly follow the MVC pattern end up copying and pasting the same security code all over their controllers.  Every place that could possibly modify data needs to check security rights.  Any place the developer forgets to do this represents a security hole.  By putting security rules in your models, you know everything is secure against hackers.   Then in your controllers you just need to worry about preventing your users from accidentally seeing security exceptions that would confuse and distress them.  The result is cleaner, more maintainable, more secure code.

Unit tests

"What about unit tests?" I hear you cry.  Good
question!  For good reasons, we like having unit tests that run on the
models without the web framework in place.  But with ModelSecurity, the models depend on the user object, which is generally a part of the web session.  So we’re kinda stuck.  Encapsulation is broken, and thus follow our unit tests.  The easy answer is to use a
global configuration setting that turns the model security checking on
and off.  When you’re processing a web request, turn it on.  When
you’re running unit tests, leave it off.  I’m thinking this should be pretty easily done in application.rb.  Or perhaps through an IOC method in the tests themselves.  But I haven’t actually revived the unit tests in this project so I couldn’t tell you for sure.  Sloppy, I know, but it’s a lot easier to justify when there’s only one coder on the project.  I’ll post an update when I dive back into this project.

Problems with Peren’s ModelSecurity gem

I’ve experienced some bizarre interactions with FCGI at least on dreamhost.  The ModelSecurity subsystem seems to crash at some point and then opens everything up to allow free access for everybody until I restart the FCGI process.  This is absolutely not acceptable.  On a somewhat similar note, sometimes basic functions will fail on first execution claiming things like "NoMethodError" but will work fine on subsequent reloads.  Having very little interest in debugging this interaction, I have given up on using Perens’ fine-grained rules.  The ModelSecurity allows you to specify very carefully which data fields can be accessed by which users under which conditions.

In my app, and many others I can imagine, it’s enough to set security at the row or object level.  This is relatively straightforward with ActiveRecord’s own callbacks. 

class SecureObject < ActiveRecord::Base  has_one :user

  #Implement model-based security  before_save :check_is_me  def after_find       # For performance reasons, you have to explicitly define an after_find method.       # You can't link it in with "after_find :check_is_me" like other AR callbacks.       check_is_me  end

  def check_is_me      if !is_me?          raise "Security exception.  Not your object!"      end  end

  def is_me?      return (User.current) && (User.current.id == self.user_id)  end

I still use a valuable construct from the ModelSecurity package,
which is the User.current class method which keeps track of who is
currently logged in thread local storage.  This global variable is what enables us to break the MVC pattern by giving the Model access to information about the User from the Controller.  Here’s a relevant snippet from Perens’ user_controller.rb:

  def User.current    # This does not refer to the session because the application has set    # this from the session in user_setup.    Thread.current[:user]  end

  def User.current=(u)    Thread.current[:user] = u

    session = Thread.current[:session]

    if session.nil?      message = "Programming error: Please add \"before_filter :user_setup\" to your application controller. See the ModelSecurity documentation."

      raise RuntimeError.new(message)    end

    # Don't cause a session store unnecessarily    if session[:user] != u      session[:user] = u    end  end

The missing ModelSecurity migration

Another problem is the lack of a migration to add the tables required by Perens’ code.  Fortunately, it’s not hard to reverse-engineer using schema.rb and the .sql files that Perens provides.  Here’s db/migrate/###_add_modelsecurity_tables.rb: (the filename is important — read on)

class AddModelsecurityTables < ActiveRecord::Migration  def self.up    create_table "user_configurations", :force => true do |t|      t.column "email_confirmation", :integer,   :limit => 3, :default => 1,  :null => false      t.column "email_sender",       :text,                   :default => "", :null => false      t.column "created_on",         :timestamp      t.column "updated_on",         :timestamp    end

    create_table "users", :force => true do |t|      t.column "login",        :string,    :limit => 40,  :default => "", :null => false      t.column "name",         :string,    :limit => 128, :default => "", :null => false      t.column "admin",        :integer,   :limit => 1,   :default => 0,  :null => false      t.column "activated",    :integer,   :limit => 1,   :default => 0,  :null => false      t.column "email",        :string,    :limit => 80,  :default => "", :null => false      t.column "cypher",       :text,                     :default => "", :null => false      t.column "salt",         :string,    :limit => 40,  :default => "", :null => false      t.column "token",        :string,    :limit => 10,  :default => "", :null => false      t.column "token_expiry", :timestamp      t.column "created_on",   :timestamp      t.column "updated_on",   :timestamp      t.column "lock_version", :integer,                  :default => 0,  :null => false    end

    add_index "users", ["login"], :name => "login"    add_index "users", ["email"], :name => "email"  end

  def self.down    drop_table :users    drop_table :user_configurations  endend

In classically annoying Rails style, if the class name of your migration doesn’t perfectly "match" the  filename then rake migrate will fail mysteriously with an unhelpful error message and a mile-long stack-trace with none of your code in it.  E.g. if you name the above file 005_add_model_security_tables.rb (note the extra underscore between "model" and "security") you’ll get an error message like this:

rake aborted!uninitialized constant AddModelSecurityTables

or if you run rake migrate --trace you’ll get this stack trace:

** Invoke migrate (first_time)** Invoke db:migrate (first_time)** Invoke environment (first_time)** Execute environment** Execute db:migraterake aborted!uninitialized constant AddModelSecurityTables/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/active_support/dependencies.rb:266:in `load_missing_constant'/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/active_support/dependencies.rb:452:in `const_missing'/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/active_support/dependencies.rb:464:in `const_missing'/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/active_support/inflector.rb:250:in `constantize'/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/active_support/core_ext/string/inflections.rb:148:in `constantize'/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/migration.rb:366:in `migration_class'/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/migration.rb:346:in `migration_classes'/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/connection_adapters/mysql_adapter.rb:248:in `inject'/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/migration.rb:342:in `each'/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/migration.rb:342:in `inject'/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/migration.rb:342:in `migration_classes'/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/migration.rb:330:in `migrate'

Then you might grep your code for "AddModelSecurityTables" and find that it’s not there because you have "AddModelsecurityTables" (difference in upper- vs. lower-case S).  This kind of thing is why Rails is still a bad choice for complex projects — a small hard-to-see typo results in the system not running and providing almost no useful feedback about what’s wrong.  And yet we keep trying to use Rails.  Because it seems to have so much potential.

Offbrain: Externalizing Memory

Posted in Ruby on Rails, Transhumanism, User Experience on May 3rd, 2007 by leodirac – 1 Comment

I’m ready to introduce a little pet project to the world: Offbrain Mobile Memory Services.  Right now it’s a very simple web app that just keeps track of lists of things.  The only thing that makes it at all interesting right now is that the UI is optimized for display on mobile browsers. 

It’s modeled after the fabulous mobile gmail interface.  Offbrain’s pages are typically between 1k and 1.5k total — they load very snappily on very slow mobile links.  (Assuming dreamhost hasn’t swapped the app or the database into virtual memory — a perennial problem with cheap shared hosting.)  And by using extremely simple HTML (think 1994) the pages display very nicely on a 240×240 pixel screen like you’ll find on a cell phone.

The idea of the service is to take notepad and list functionality that has been standard in PDAs and PIMs forever, and move it into the information cloud.  Make it accessible through web, e-mail and SMS so it’s accessible anywhere you have a cellphone.  This way you’ll never forget to bring your shopping list to the store again because you’ll always have your phone with you.  Even better, since it’s stored in the cloud, you and your family members can share a group list, which would never have been possible with paper or traditional PDAs.

My buddy Ben and I even came up with a cool way to monetize this free-to-consumers service as a business.  We entered the idea in the UW Business Plan Competition which provided me the necessary motivation to build the beta that’s now live and to do the necessary research into how to connect it to a real SMS gateway.  (Thanks to Jordan Schwartz for all the tips.)

My real goal of course here is to support the upcoming robot revolution by encouraging people to move more of their active minds into computers.  Encourage is a strong word.  Enable.  Moral capitalism requires offering services that are mutually beneficial to all parties with full disclosure of all known information.  By this criterion I think I’m totally in the clear so long as I explain to y’all what I’m up to.

Once I actually wire up the SMS interface, I’m gonna totally use this all the time.  Anytime I want to remember something and I don’t have my journal in front of me, I’m just gonna whip out my cell phone and send a text message to my external brain (my Offbrain) so it’ll remember it for me.

And yes, despite all my whining, I wrote it in Ruby on Rails.  Annoying as the language is for complex projects, it works really nicely for a quick and dirty app like this.

Problems Scaling Ruby to Complex Systems

Posted in Personal Growth, Ruby on Rails, Software Engineering on March 4th, 2007 by leodirac – 7 Comments

I’m pretty annoyed with Ruby right now.  At least I feel that way.  Looking a little deeper I realize the source of the annoyance is, like usual, my own shortcomings.  My friends and I embarked on a software project a while back.  I helped talked the group into using Ruby on Rails as the framework over choices like Java or .net because I was excited about it.  Many had reservations.  Today I’m annoyed at myself for not listening to them more.

The biggest problem with an uncompiled language is that there’s no compiler to tell you when you’ve screwed something up.  The incredible power and flexibility you get from Ruby’s loose dynamic typing and mixin inheritance style means that the IDE and compiler really have no idea what’s valid when you type it.  Compare this to Eclipse for Java or Visual Studio for .net where once you type ‘objectname-dot’ there’s a list of valid methods you can call and what kinds of parameters they take.  If you get it wrong, there’s a red squiggly underline saying something is wrong before you’re on to the next line of code. 

Yesterday 3 reasonably good software engineers took a solid 3 hours to figure out that we were passing the wrong class of argument into a method.  The problem was exacerbated by the behind-the-scenes magic that Rails does to try to make your life easier.  We were passing a Tmail object into ActionMailer.receive, which might seem to make sense since the receive method that everybody who uses ActionMailer writes expects a Tmail object as an input.  But we had forgotten that you’re not supposed to call this method.  In fact ActionMailer makes it impossible to directly call the method we wrote.  Instead you’re forced to call the class method, which we had forgotten expects a string as input that it parses into a Tmail object for you.  And like usual, the error message is useless.  Bad error messages are the single biggest flaw with Ruby on Rails IMHO.  (Maybe just the easiest to fix compared to the other problems.)  This was particularly frustrating because we spent an entire day tracking down something that any strongly typed language would have caught instantly.

For a long time, I’ve argued that people should use the highest level programming language they can afford to.  A huge advantage of pointerless languages is that you can’t make pointer mistakes.  It’s simply not possible to write that kind of bug in the higher level language.  Coding therefore become faster and more reliable than in a lower-level language.  The only cost is run-time performance, and if you’re writing server code as most of us do these days, then scalability is generally not limited by performance.  I had assumed that this analogy would continue from managed-code languages up to the hottest new scripting language that seems like it’s flexibility might fulfill OO’s promise of code re-use.  Today I’ve changed my mind.  Ruby is not a higher level language than C# or Java. 

Conceivably, a really good IDE could make up for a lot of this.  But due to the run-time binding in Ruby it would never be perfect.  When selecting a development system, generally I think the language itself is really unimportant compared to the quality of the tools and libraries available.  OO languages are generally about the same.  But IDE’s matter so much.  And libraries determine how much you have to write yourself vs. using what others have done before you.

A friend asked me if I was writing this as a warning or a cry for help.  It’s both.  It’s a warning about the scalability limits of Ruby.  Many people intuitively suspect that Ruby on Rails won’t scale well, but they confuse the different types of scalability.  The most common complaint about Ruby is that its runtime performance is too slow to scale well.  As Cal Henderson’s wonderful book on website scalability points out, raw performance does not matter if you can add more servers, which you can with RoR.  But as I learned yesterday, Ruby on Rails does not scale well in terms of complexity.  A friend once aptly pointed out that 43 things was the largest site anybody had managed to build in RoR to date.  The current state of tools and libraries and aspects of the language itself make it extremely difficult to write and maintain large complex projects with many developers.

It’s also a cry for help, but not for our particular project.  You’ll see it soon enough.  It’s a request that if you’re working on Ruby or Rails, please invest in the tools and the robustness of the libraries.  The error messages in Rails are total crap, as I’ve mentioned a couple times before.  And the IDE’s really need to improve if the framework is going to see major use beyond hobbyists.

How to fix failed migrations for “Lost connection to MySQL”

Posted in Ruby on Rails on December 16th, 2006 by leodirac – 1 Comment

Yet another in the long series of "why does rails give such useless error messages?"  I could migrate in the development environment fine, but when i tried to migrate in the test environment, I got this:

C:\dev\radrailsws\snorb>rake migrate RAILS_ENV=test(in C:/dev/radrailsws/snorb)rake aborted!Mysql::Error: Lost connection to MySQL server during query: SELECT version FROMschema_info

After a bit of digging I thought it was because the mysql account in the test environment is different from development, so I ran this to grant full permissions:

mysql> grant all on snorb_test.* to unit_test_userQuery OK, 0 rows affected (0.00 sec)

But that didn’t work either.  I ended up having to let the test environment use the root mysql account, which I didn’t want to do, but that certainly fixed the problem.  I’ve suspected there’s something funny going on with the test environment database credentials for a while, but I can’t quite pin it down.

Here’s the full set of errors I was getting from the system in case it helps anybody find this problem… 

C:\dev\radrailsws\snorb>rake migrate RAILS_ENV=test(in C:/dev/radrailsws/snorb)rake aborted!Mysql::Error: Lost connection to MySQL server during query: SELECT version FROMschema_info

(See full trace by running task with --trace)

C:\dev\fritz\radrailsws\snorb>config\environments\test.rb

C:\dev\fritz\radrailsws\snorb>rake migrate --trace(in C:/dev/fritz/radrailsws/snorb)** Invoke migrate (first_time)** Invoke db:migrate (first_time)** Invoke environment (first_time)** Execute environment** Execute db:migraterake aborted!Mysql::Error: Lost connection to MySQL server during query: SELECT version FROMschema_infoc:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract_adapter.rb:120:in `log'c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:184:in `execute'c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:336:in `select'c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:179:in `select_one'c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:307:in `current_version'

Missing GEM causes misleading “use_transactional_fixtures” error

Posted in Ruby on Rails on October 31st, 2006 by leodirac – 1 Comment

A lot of people out there on the net are getting frustrated by this error message coming out of their unit tests:

    undefined method `use_transactional_fixtures=' for Test::Unit::TestCase:Class (NoMethodError)

I was recently getting this in my unit tests on my continuous integration server.  The problem is that this has message nothing to do with the actual error.  Rake has this bad habit of silently swallowing useful errors.  Sometimes is just stops without saying anything, and other times it gives a completely incorrect message like this one.

In my case, the problem was a missing gem on the continuous integration server.

I’ve been working on patches to address these bad-error-message issues, but I haven’t yet gone through the effort of figuring out how to contribute them into the master source tree.  I haven’t developed a patch to catch the root cause behind the ‘use_transactional_fixtures’ error above yet.  But here’s one that catches database config errors and a bunch of others that would otherwise be silently swallowed:

Go into /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/tasks/testing.rake and change the task :test method to read:

desc 'Test all units and functionals'task :test do  error_place=""  Rake::Task["test:units"].invoke       rescue error_place += "test:units: #{$!}"  Rake::Task["test:functionals"].invoke rescue error_place += "test:functionals: #{$!}"    if File.exist?("test/integration")    Rake::Task["test:integration"].invoke rescue error_place += "test:integration: #{$!}"  end

  raise "Test failures in #{error_place}" if error_place != ""end

Compare to the official version.  Note what happens to exceptions: nothing.  This patch has been invaluable for configuration on my CI server.  To repeat, this patch does not address the "use_transactional_fixtures" error.  When I figure out a patch for that one I’ll post it.

Chinese characters in Mysql: Dont forget the collation

Posted in Databases, Ruby on Rails, Software Engineering on October 16th, 2006 by leodirac – Be the first to comment

I recently conquered another oddity in using chinese characters in MySql.  Apparently, it’s not enough to set the database’s character set to UTF-8.  You also need to set the collation to a utf-8 collation.  You might think the collation is only important for sorting, but theres’ more to it.  If you have selected a case-insensitive collation, then it is also used to determine equality.  If the collation doesn’t understand character boundaries properly, then you run into strange problems.  The database was convinced two very different chinese characters were the same because their UTF-8 encodings when interpretted as 1252 had similar characters, maybe only differing in case or accent.

So if you’re having trouble with unicode characters in mysql, try running this command:

mysql> alter database chinesedb collate utf8_bin

Next step is figuring out how to put this into an ActiveRecord migration.

Ruby + MySql weirdness

Posted in Ruby on Rails on October 1st, 2006 by leodirac – Be the first to comment

I’m posting this because I didn’t see any quick answers on google when looking for other people having my problem.  Recently all the unit tests for one of my Ruby on Rails projects started failing mysteriously.  The continuous integration server didn’t report any problems, but on my windows dev box (where I use instant rails) nothing would pass.  The errors came out like:

 15) Error:test_update(Admin::ConnectionControllerTest):ActiveRecord::StatementInvalid: Mysql::Error: Lost connection to MySQL server during query: DELETE FROM connections    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract_adapter.rb:120:in `log'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:184:in `execute'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:199:in `delete'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:283:in `delete_existing_fixtures'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:256:in `create_fixtures'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:256:in `create_fixtures'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract/database_statements.rb:51:in `transaction'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:255:in `create_fixtures'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:794:in `silence'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:248:in `create_fixtures'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:565:in `load_fixtures'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:512:in `setup_with_fixtures'    c:/dev/fritz/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/fixtures.rb:547:in `setup'

The problem apparently is caused by the fact that I put a password on the mysql login credentials in the test environment.  Removing the password on the login made it work just fine.  So I guess something about the ruby mysql driver didn’t like the way my mysql server was configured.  Anyway, upgrading to Mysql 5.0 (from 4.1) fixed everything.  Not sure if this is a problem with the version of instant rails I have, or something about my database config, or if one of the libraries autoupdated to a non-compatible version, but it’s fixed now so I don’t much care.

Hope this helps anybody else out there who runs into a similar problem.