David Stevenson's blog



Interesting Things

  • require "psyche"; require "yaml"? WRONG! We've found you have to do them in opposite order or your parsing is "all screwed up".

Ask for Help

"Rubymine is excluding code in our gem's spec/ directory from being indexed, can that be changed?"

We assume this is an optimization, because most people aren't interested in anything from a gem except the lib/ directory. There doesn't appear to be a way to change this behavior.

"How can I override the gem version requirements on annoying gems in my project?"

We're trying to bring in rails 2.3.2 + rack 1.1.x, but rails explicitly requires the old version of the rack gem. Can we do something sneaky to change the requirements without forking and modifying the gem??

"Is there a good set of practices for exposing ActiveRecord models to JavaScript?"

Like using Backbone.js model support? Or maybe just straight #to_json on models and embedding them into HTML templates?

David StevensonDavid Stevenson
Standup 5/10/2011: How safe are you videos over RTMP?
edit Posted by David Stevenson on Tuesday May 10, 2011 at 01:48PM

Ask for Help

"Is flash RTMP streaming a secure way to stream video so it can't be downloaded?"

We're using this with CloudFront + S3. But will it protect our content enough?

"RubyMine + rspec 2.6, why won't my focused tests run?"

We hoped this could be easily fixable by detaching the rspec gems and reattching them, but no luck with our usual fixes.

"MixPanel, is it a good tool for analytics and log analysis? "

Compared to normal analyics tools or splunk for log analysis?

"Anyone ever stubbed out 3rd party calls to a Thrift RPC service before?"

Is there a better solution than some sort of standard generic ruby stubbing & expectation tool?

Interesting Things

  • Postgres is giving us some weird behavior on Heroku when we have column names longer than 27 characters. We think the update_attribute calls are not being persisted but no errors are generated.
  • There are finally some viruses/trojans for mac OSX that are gaining traction. Careful what you download!
  • The net-ssh-telnet gem makes running a scripted batch SSH session pretty easy. This might be a good tool for you, if you want something much less complicated than capistrano or chef server for remote automation.

Ask for help

  • We just upgraded one project from Devise 1.1 to Devise 1.2 and reported "many problems which blew up all sorts of stuff". It was bad enough we had to rollback. Are there others with failure or success stories for this upgrade?
  • Can you rate limit EC2 nodes using an Elastic Load Balancer? We'd like to cap the amount of traffic that can be sent to an app instance. I'm thinking advanced use cases like this are probably why you run your own haproxy instead of using ELBs.
  • How are people running database migrations in their engine gems? I know rails 3.1 promises to bring this to the table, but is there a backport gem we can use?

Interesting

  • iOS 4.2 is out! We're looking forward to trying it on the iPad (finally).

Interesting Things

  • has_many and belongs_to associations can now automatically create back references each other, thanks to a Backport of :inverse_of from Rails 3 to rails 2.3.6. This allows us to keep our object graphs more correct and avoid situations where we have 2 copies of the same object because the object graph is walked in reverse. Here's how to use it:
class Parent < ActiveRecord::Base
  has_one :child, :inverse_of => :parent
  accepts_nested_attributes_for :child
end

class Child < ActiveRecord::Base
  belongs_to :parent
  validates_presence_of :parent
end

Ask for Help

"We keep getting webrat thread exceptions running our integration specs with the rails integration runner: Thread tried to join itself. The error message varies with different versions of ruby 1.8.6 vs 1.8.7."

Anyone had this problem or know why?

"How do I skin an iphone mobile site to be the correct width so it's not 980px wide?"

<meta name="viewport" content="width = device width" />

*"We're trying to deploy some nginx configuration changes to EngineYard Cloud, what's the right way to do that?"

We've tried building custom chef recipes to solve this problem, but they run after nginx has already restarted, so are a poor solution to this problem. The better solution might be to check in configuration files into the application and symlink them into the nginx configuration directory using a before_symlink.rb hook in the /deploy directory.

*"We've got a has_many association where some of the child records are originally saved in an invalid state. When we later load the parent and ask it if it's valid, it returns true even with validates_associated. How can we get the desired validation behavior?"

Turns out that unloaded associations are not validated. Solution: load the association before calling .valid? on the parent. In general, you should also not create invalid objects, instead using a state variable to put them into a "draft" or "incomplete" state where they are still valid but not complete. Then remove that state and you'll see the errors required to finish that object.

Interesting Things

  • When RubyMine 2.0.1 won't run your focused specs, try attaching rspec 1.2.9 to it rather than 1.3.x. It fixed this issue for one of our teams.
  • Rubymine 2.0.2 came out today: can finally run focused contexts?! Also including bundler support! What's new
  • We tried our Unicorn on EngineYard cloud: so far so good. It's still "experimental" but seems to work.

David StevensonDavid Stevenson
Standup 4/26/2010: Ruby hack night with Sarah Mei
edit Posted by David Stevenson on Monday April 26, 2010 at 10:03AM

Interesting Things

  • Given a list of IDs, how do you find which ones are not in the database?
ids = [1,2,3,4,5,0]
missing_ids = ids - Model.find_all_by_id(ids).collect(&:id)
  • Sarah Mei is hosting a Ruby Hack Night at pivotal labs tomorrow at 7PM (Tues April 27th. 731 Market St Floor 3, San Francisco).
  • There is an android users group tomorrow. We don't know any more about it than that.

Interesting Things

  • Be careful when extending classes from structs. Their superclasses are essentially anonymous classes, so reopening them can be difficult. If you attempt to reopen them by extending them from "the same" struct, it will actually be a different anonymous class.
  • Ever had an STI model but wanted the views and controllers to pretend like it all extended the base class? You can have rails change the params[] namespace that it uses like so:

    form_for :user, @admin_user, :url => user_path(@admin_user)

Or you can be super-cool and use polymorphic routes:

form_for @admin_user.becomes(User)

The becomes method is part of ActiveRecord, and it actually creates a 2nd copy of the object with the same attributes and a different class (shallow copy). Due to this implementation, it has limitations so use it carefully.

  • Upgrading to rails 2.3.3 breaks HopToad. This is related to filter_parameter_logging, and it's technically rails' fault. It has been fixed in 2.3.3 stable (which I assume will be released as 2.3.4). You can also fix it yourself with a one-line-patch. Personally, I'd wait to upgrade till 2.3.4 comes out.

David StevensonDavid Stevenson
Standup 08/25/2009: Mechanical turk for data matching
edit Posted by David Stevenson on Tuesday August 25, 2009 at 09:34AM

Interesting Things

  • One of our projects is using mechanical turk to match and normalize their ugly data. After building some automatic matching with little success, the group is simply using the template web interface. The task can be trivially decomposed into tiny tasks, and accuracy does not need to be 100% perfect, so it's a great fit. They only spent a few hours and have results already!

When creating associations to classes that use Single Table Inheritance (STI), rails is smarter about the hierarchy than I would have expected. A call to find on a base class yields a query that does not filter on type. But what about a call to find on a subclass? Instead of making a single filter on type, rails finds all the subclasses of that subclass and creates an "OR" expression in the "WHERE" clause.

Generated SQL respects class heirarchy

# ActiveRecord::Base < User < Admin < SuperAdmin 
something.admin    # has_one :admin

Generates the following SQL:

# SELECT * FROM users WHERE (type = 'Admin' OR type = 'SuperAdmin')

When it doesn't work

Since it relies on the class hierarchy, the query is only accurate if every subclass has been loaded. If class preloading is off, for example, very weird things can happen. The query will depend non-deterministically on which subclasses have been loaded.

Other articles: