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.

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.

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.

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.

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:

Interesting Things

When using standard rails partials you always have a local variable named _counter. In previous versions of rails, the partial_counter variable was set to 0 when you passed an object, and set to 1 for the first item in a collection. Now it appears to start at 0 whether you pass an object or a collection.

Our site has a number of buttons which are: (a) really links which look like buttons instead of links, (b) ajaxy actions, which typically cause an edit box to appear, or (c) form submissions. This item is especially about (a) and perhaps (b). Right now we have what is a glorified styled a tag, as described here. We’ve been having trouble getting that to work right (in particular, the height seems off by one pixel in mysterious circumstances). Probably the easiest solution is the rails button_to helper, which makes a form with one button in it (and method=get). This loses some desirable behaviors of the a tag (such as being able to control click or menu-click to open in a new tab), but certainly solves the rendering hassles.

Selenium on several machines was failing with Connection Refused errors. This turned out to be caused by IPv6 entries (for example, “::1 localhost”) which were added by a recent MacOS upgrade. Commenting out those entries seemed to fix the problem (or work around it, anyway).

Some people expressed a style preference, in rspec, for “pending” rather than an empty “it” block, to make it easy to search for pending tests. Excessive pending tests may be an anti-pattern. On the other hand, writing pending tests, at least temporarily, may be a good way to sketch out an area of functionality before it is implemented.

We have sometimes found that editing selenium tests (but not other ruby files) in IDEA is incredibly slow (as in, 30 second pauses). Two things to try are removing the gems directory from the project (in favor of just those gems which you need to be able to look at in IDEA), or at least removing the selenium gems. Another such example is that IDEA can be really slow editing the end of a long fixture file. This is probably IDEA 7.0.3 or 7.0.4.

Interesting Things

One of the teams was trying to reopen the Time class to make to_date public. Another pivot noticed that there is no built in to_date in Time class in ruby. ActiveSupport has a to_date method on Time class that is public. The most interesting one is that there is a private to_date that is added to Time class when you include Yaml.

Other stuff

We are looking for one more unix system administrator preferably with scalability experience to help with our infrastructure. The job description is here. Well there are obvious benefits and then there is also free breakfast :)

What’s the best way to import a million records into a postgres database via ActiveRecord (which is needed to implement some application-specific logic)? We anticipate waiting a second (or so) between inserts to avoid slowing down the production database (which is under load, almost entirely reads). If there is any ActiveRecord feature which helps batch together inserts, noone knew about it. As for generally how long this will take (estimates range from 9 to 27 hours), and what the load on the production database will be, we planned on answering that with a trial run of a small number of these records.

We’re thinking of having capistrano deploy to two demo servers, one particularly aimed at showing to prospective users of our application, and the other mostly for story acceptance. The former would be hosted at a hosting company; the latter an internally run machine. Several people reported they have done this on their projects, and the problems were minor, mostly having to do with whether the deployed location (/u/apps/whatever or some such) is different on the two machines (the solution would be to use the capistrano variables, but tracking down all the places that need to do that could be an issue).

Erector tip of the day: in a Rails project, you can put a file (named edit.rb or edit.html.rb) in your view directory, and Rails/Erector will find the template implicitly (as it would for ERB, HAML, etc). It is not necessary to explicitly call render from your controller method.

All of this path-checking can sometimes be quite expensive, especially in the case of svn log. When retrieving a list revisions, the server looks at every changed path in each revision and checks it for readability. If an unreadable path is discovered, then it’s omitted from the list of the revision’s changed paths (normally seen with the –verbose option), and the whole log message is suppressed. Needless to say, this can be time-consuming on revisions that affect a large number of files

Check out the new links at pivotallabs.com

Talks lists all the tech talks that happen here at Pivotal such as Blaine Cook’s Fire Eagle talk. If you have some cool technology and would like to give a talk, contact us at techtalks@pivotallabs.com

In order to accomplish some advanced search functionality, we’ve added a lot of named_scopes to our User model. This seems like a good idea, and well within the intended use for named_scopes. Unfortunately, we ran into issues with our :joins. We have a separate User and Profile model, but our advanced search scopes often needed both to make decisions. So we had some scopes that look like this:

Using these named_scopes, we wanted to dynamically construct a finder that would return the results the user was interested, such as: User.verified or User.answered_questions or even User.verified.answered_questions.with_name('Joseph'). The last scope caused issues, unfortunately, with table aliasing. The query ended up joining in the profiles table twice, in exactly the same way without renaming the table, so mysql rejects the query.

The easiest solution to this problem was to use only the hash form for :join clauses, such as :join => :profile. Rails correctly merges multiple consecutive join scopes that use hashes. If you need to use string joins (such as a LEFT JOIN rather than an INNER JOIN) or put a condition directly on your join, then merging goes out the window and the hashed form is immediately converted to a string and all consecutive joins are “merged” by appending them together.

We started by manually aliasing our scopes, but in some cases we were concerned about the amount of duplicate data this was causing in our queries.

We thought about creating a dependency framework for named_scopes, such that you could have a single :profile scope that other scopes were dependent on and it would only ever get added once. This seemed really difficult because of the way the with_scopes are constructed by named_scopes, there was no good place to keep track of these dependencies, and it would still cause problems if you had a manual with_scope, or :join in your find.

Finally we decided that rails fundamentally lacked the capability to deal with duplicate joins, and that we should solve this problem. It seemed a good solution was to allow :join options to take an array of strings as follows:

Now calling User.answered_questions.with_name('Joseph') will create three values in a :join array, two of which are identical and will be uniq’d out. The downside to this approach is that each value in the :join array has to be string identical, or it will not be properly uniq’d.

So if you are mixing hash style :profile joins with string joins of the same table you need to be careful you match the rails generated syntax. We mostly use string style joins to avoid this issue.