Nathan Wilmes's blog



Nathan WilmesNathan Wilmes
Standup 12/28/2009: Rspec 1.2.9 and mocking flash
edit Posted by Nathan Wilmes on Monday December 28, 2009 at 09:24AM

Ask for Help

"Ever since we upgraded to RSpec 1.2.9, we haven't seen any stack traces. What gives?"

One of our projects lost stack traces as soon as they upgraded to RSpec 1.2.9. Reverting to RSpec 1.2.8 fixed the problem. No other projects have reported the issue yet.

Interesting Things

  • Working with Rails for several years means that, as Rails advances, our testing/mocking codes get stale. We just discovered that one of our old mocks for representing the 'flash' object no longer works as designed with the current version of Rails.

Nathan WilmesNathan Wilmes
Standup 12/23/2009: Load/require and Rails reloading
edit Posted by Nathan Wilmes on Wednesday December 23, 2009 at 09:27AM

Ask for Help

"What's a good design for sharing a page cache across multiple servers?"

One of our clients would like to have a distributed server environment share its page cache. At this point, they're relying on GFS to do this.. but this solution appears to have problems with reliability.

Several engineers questioned the necessity for such a thing, but memcached appeared to be the solution of choice.

"Any information on RabbitMQ?"

One of our engineers is beginning to play with RabbitMQ. Anyone who has good comments about this technology, please feel free to chime in.

Interesting Things

  • load "location" and require "location" do not play nicely with Rail's automatic class reloading.

Rails maintains an internal array of files that it 'knows' about for this purpose. However, load and require bypass this mechanism, and lock files into place.

If you'd like to add a require that will class-reload, use the command 'require_dependency "location"'. This command, added by Rails, will require the file AND add it to ActiveSupport.

Nathan WilmesNathan Wilmes
Standup 12/21/2009: Bundler and symbol.to_proc
edit Posted by Nathan Wilmes on Monday December 21, 2009 at 09:47AM

Ask for Help

"How do I make attachment_fu use both the file system and S3 as storage backends?"

One of our clients would like to migrate attachments from the file system to S3. They want a clever way to make attachment_fu look in S3 or the filesystem, where new files are in S3 and old files are in the filesystem.

Their current solution, which they're not super happy with, is to monkeypatch the S3 backend by extending it with file system methods. This solution doesn't really seem to work too well, since the two backends share some of the same methods, and calling "extend FileSystemBackend" doesn't give them the freedom to pick and choose their methods. In addition, their patch makes the S3 backend not be an S3 backend any more, which could cause problems for maintenance down the road.

A better solution is to define a new backend object, based on the S3 backend but falling back to file system-style methods. Attachment_fu supports defining custom backend modules; a class using :storage => :my_storage would look for a backend module called Technoweenie::AttachmentFu::Backends::MyStorageBackend.

Attachment_fu still has a design problem. The backend objects are all modules, not classes. As a result, it's not easy to make a new backend descend from one of the existing backends.

Interesting Things

  • The new version of the bundler gem, version 0.7.2, does not seem to be Ruby 1.8.6 compliant. The gem relies on symbol.to_proc, which is part of Ruby 1.8.7 (and Rails). A native Ruby 1.8.6 without Rails does not support this method.

Issue tracking: http://github.com/wycats/bundler/issues/#issue/134

Nathan WilmesNathan Wilmes
Standup 10/10/2008
edit Posted by Nathan Wilmes on Friday October 10, 2008 at 04:21PM

One interesting thing this morning:

The RailsEnvy blog had a segment talking about a team of engineers building a series of social network plugins using the Pivotal Lab's technology: Dessert.

Those of us used to Desert (one 's') were wondering what Dessert might be, leading to this quip from Adam:

"Dessert is Desert with a lot of syntactic sugar."

Nathan WilmesNathan Wilmes
Standup 10/8/2008 - testing Flash and routing helpers
edit Posted by Nathan Wilmes on Wednesday October 08, 2008 at 04:17PM

Ask for Help

One of our clients is looking for high-quality third-party chat services/libraries.

Interesting Things

10.5.5 and screen sharing

The Mac screen sharing application includes a host of interesting power features. Unfortunately, upgrading to Mac 10.5.5 causes these features to go away. Workarounds at this point are to store off the application and re-install it. Or to pay $300 for the official solution. Whichever.

Additional routing-related helper methods

It can be useful to create helper methods designed to extend the routing helpers offered by routes.rb.. power "_path" and "_url" methods. While the easy solution is to define these methods in your view helper layer (the most common client of these methods), a more complete solution is to use a pattern like this:

in routes.rb:

          ActionController::Routing::Routes.draw do |map|
               ... normal routes ...
          end

          ActionController::Routing::Helpers.module_eval do
             def additional_method_name
              ...
             end
          end

Any methods added to ActionController::Routing::Helpers will be available in all of the same places that named routes are defined - controllers, views, and ActionController::UrlWriter includers.

Testing Flash in Selenium

Most Flash applications render an inline image in addition to the Flash itself. This image updates as the Flash updates, and appears to be used for caching purposes.

When you're test-driving, you can make assertions about when this inline image updates to test Flash behavior. The image is binary, so it's hard to make assertions about exactly what has changed.. but it's a start.

Nathan WilmesNathan Wilmes
Standup 10/7/2008 - Namespaces, class names, and PostGRES
edit Posted by Nathan Wilmes on Tuesday October 07, 2008 at 05:01PM

Ask for Help

When using a namespaced controller, it's hard to get url_for to work with it. Why is that?

  • The controller option for url_for attempts to apply the namespace of whatever controller context it's inside. So if you have an Admin::MyController class, here's what you would need to do for url_fors to this controller:

    • from within an Admin controller class: :controller => "my"

    • from outside an Admin controller class: :controller => "admin/my"

    • for a partial that is used all over the app: :controller => "/admin/my" seems safest
  • Most of us now avoid using url_for-style hashes for our links and URL references. Named routes are a lot more dependable.

  • It is possible to generate a namespaced URL from a model reference, if you are careful.

    • This approach assumes that your controller class names correspond to your model class names.
    • If your model is @model, and your controller is Admin::ModelsController, you can use a helper like the following:

       form_for [:admin, @model] do |f| ... end
      
    • This approach can limit your design, if you rely too heavily on this convention.

Interesting Things

How to read your class's name

While working with the UltraSphinx plugin, Davis and Brandon learned that Class.name didn't always give them the right results. Some of their classes had a class method override what Class.name returned.

Class.class_name came closer, but returns the base class for STI (single table inheritance) classes.

Class.to_s was their most reliable option.

Testing your app on both MySQL and PostGRES

David S. is working on a plugin that allows you to test your environment on multiple databases. Since we're starting to have more projects using PostGRES, we're uncovering situations where some of our common code makes too many assumptions about running on MySQL.

Slutty namespaces

A couple of projects ran into mysterious issues where some of their namespaced controller classes would not load when run from rake.

The culprit was that their namespace module names were the same name as their app models. The lesson - never have a module with the same name as one of your other unrelated classes. (No, I'm not talking about inner classes, which can be fine).

A prime example of this is an Admin::* namespace coexisting with an Admin model. This will cause strange problems depending on what order the classes are loaded. One recommendation is to pluralize your namespaces. In this case, your namespace would be Admins::*.

Another suggestion would be to use an extended noun form for your namespace (Administration::*). Whatever convention you use, stick to it and avoid name collisions.

Nathan WilmesNathan Wilmes
Standup 10/6/2008 - Namespaced controllers and MySQL ordering
edit Posted by Nathan Wilmes on Monday October 06, 2008 at 04:51PM

Ask for Help

David and Jonathan are having trouble with testing namespaced controllers using RSpec. They have two controllers, Admin::MyController and SuperUser::MyController, and the RSpec tests appear to be finding the wrong controller.

Their short-term solution is to put a manual require in the spec that was getting confused.

UPDATE - The issue turns out to be a naming conflict. The app has a model named SuperUser, and the existence of this model can cause class loading to be confused for SuperUser::* controllers. In Socialitis, our standard is to use plural names for controller namespace names, to prevent this sort of confusion.

Interesting Things

Steve has learned that, in general, it's a good idea to avoid using offsets when manipulating large quantities of data in MySQL. Luckily, some of MySQL's quirks help with this:

  • MySQL sorts indexes. The primary key is the main index that it sorts.
  • Any select without an explicit order clause will pick an index, then return data in sorted order by that index. Again, usually you'll see the primary key first.
  • You can take advantage of this behavior to paginate through a large dataset where the order doesn't really matter. The following statements perform better than your typical LIMIT/OFFSET clause:

    SELECT * FROM big_table WHERE id > 1 LIMIT 1000
    SELECT * FROM big_table WHERE id > 1000 LIMIT 1000
    SELECT * FROM big_table WHERE id > 2000 LIMIT 1000
    
  • acts_as_solr uses this technique for reindexing.

  • Also, inserting a record in the middle of an id 'hole' is not a very good idea in MySQL, because the database then puts a great deal of work into reordering all of the later records.

Here's a link to a related blog post: http://weblog.jamisbuck.org/2007/4/6/faking-cursors-in-activerecord