Testing HTTP Authentication

If you ever need to test HTTP Authentication in your functional tests, here is how you do it:

1
2
3
4
5
6
def test_http_auth
  @request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials("quentin", "password")
  get :show, :id => @foobar.id

  assert_response :success
end

This is much like testing SSL.

Hat tip: Philipp Führer for Functional test for HTTP Basic Authentication in Rails 2.

Getting Started with MongoDB and Ruby

mongo mapper MongoDB a is a high-performance, open source, schema-free, document-oriented database written in C++. It’s sort of a cross between scalable key/value stores and traditional functionality-rich relational databases.

MongoDB might be useful as a fast, simple, non-transactional data store for a web application, or as a caching mechanism. You don’t ever need to worry about migrations due to Mongo’s schema-less nature.

Getting started with MongoDB using Ruby is now fairly straightforward thanks to the Mongo Ruby driver. This provides access to the core Mongo database operations, and natively supports many Ruby objects without requiring conversion (including nested hashes). There’s even an ActiveRecord connection adapter for Mongo.

Earlier this week, John Nunemaker announced his MongoMapper, a wrapper for MongoDB which includes typecasting, callbacks, validations and other ActiveRecord-like features. The project is heading towards drop-in Rails compatibility.

MongoMapper uses a default connection from the Ruby driver, and to create a MongoMapper model you just need to include MongoMapper::Document in the class (as opposed to ActiveRecord’s inheritance pattern). From there, it’s simple to define your document’s keys, validations and callbacks.

The MongoMapper gem is available from RubyForge or Github, and you can read more on RailsTips.

rupho.pngAlso worth seeing.. Mobile Orchard’s Beginning iPhone Programming Workshop. Bay Area/July 30-31. Seattle/Aug 20-21. Ruby Inside discount of $200 — use “ri” discount code.

6 Reasons to use Webbynode

Recently I put together a video for the guys over at Webbynode. Webbynode is a very affordable VPS host (256 RAM for $15) which has great support for Rails applications. Why should you consider using Webbynode? Just watch the video.

Back in the early days of Rails you could find cheap hosting plans that gave you great Rails support. Since then it’s become harder to find middle ground between shared hosting on Dreamhost and managed hosting on Rails Machine or Engine Yard. A few months ago I was lucky enough to run into Carlos Taborda, who was just launching the beta of Webbynode. I decided to give Webbynode a try to run the Ruby Hero Awards.

Since then I’ve been really impressed by the progress made by the Webbynode team, and I think they’ve created an awesome product for the Rails community. Why have they impressed me?

  • Rails Support – I love the idea that if I run into trouble on my Webbynode VPS, I can go direct to a Campfire room or IRC and get helpful support. This is so important when you find yourself troubleshooting an issue for hours, and need a little extra help.
  • Readystacks – Readystacks allow developers who don’t have experience with system administration to very quickly get up and running with a Rails server. Just like Rails scaffolding is a great starting point for an app, Readystacks serve as a great starting point for a VPS setup. Back in the day RailsMachine had their “5 minute deploy” script which was cool, but Webbynode did it one step better by providing an easy to use web interface that kicks ass.
  • Full Access – Like I said before, Readystacks are great starting points, but nothing beats having full and complete (root) ssh access to configure your servers. I just can’t imagine deploying a client’s application on a production box without it, and Webbynode gives you the keys to the castle.

So, check out the video, and maybe next time you need another VPS, give Webbynode a try.

Guest Blogging

I’ll occasionally be posting on the Engine Yard blog in addition to my posts here. Union Station has really stepped up lately in terms of technical content. We’ve had posts on pairing, TDD with Cucumber, Rack and a slew of other things, and I know there’s more in the pipe.

I posted today on how we’ve been refactoring Rails, and how you can apply what we’ve learned to your own projects: let me know what you think!

#168 Feed Parsing

Learn two different techniques for parsing an RSS feed using Feedzirra in this episode!

#168 Feed Parsing

Learn two different techniques for parsing an RSS feed using Feedzirra in this episode!

Ruby FreshBooks Integration

Having trouble integrating FreshBooks? So were we.

Some gotchas:

  • The README is often incorrect.
  • Update doesn’t work. Use our gem.
  • Status for estimates is an integer, not string: 1 draft, 2 sent, 3 viewed, 4 replied
    5 accepted, 6 invoiced
  • Check the result for invoice.update. If it’s false, there’s an error. Edit the gem to turn on debug statements around lib/freshbooks/connection.rb:call_api
  • To download the pdf, you must set the status to ‘sent’ for a draft (remember to set it back!).
  • Install it: gem install elc-freshbooks.rb –source http://gems.github.com

Full code to download an invoice or estimate PDF:

  def get_pdf(inv_or_est)
    is_draft = inv_or_est.status == 'draft'
    if is_draft
      inv_or_est.status="sent"
      update_success = inv_or_est.update # Fail if this is false
      raise "FreshBooks API has changed. Document could not be readied." unless update_success
    end
    logged_in_session_to_view_doc_url = inv_or_est.links.client_view
    cookiejar = Tempfile.new("cookies")
    # Note this is particularly ugly because we require session cookies + redirect handling + bad SSL chain (thanks godaddy!). Bailed on Net::HTTP approach.
    html_doc = `wget "#{logged_in_session_to_view_doc_url}"  --no-check-certificate --cookies=on --keep-session-cookies --save-cookies='#{cookiejar.path}'  -O -`
    # https://elc.freshbooks.com/getPDF.php
    if inv_or_est.class == FreshBooks::Estimate
      pd = "estimate"
    else
      pd = "invoice"
    end
    pdf_file = Tempfile.new("pdf")
    cmd = "wget 'https://#{self.freshbooks_api_host}/getPDF.php' --post-data='#{pd}id[]=#{inv_or_est.number}' --cookies=on --keep-session-cookies --load-cookies='#{cookiejar.path}'  --no-check-certificate -O '#{pdf_file.path}'"
    pdf = `#{cmd}`
    logger.debug "Get the actual PDF: #{cmd}"
    cookiejar.delete
    if is_draft
      inv_or_est.status="draft"
      update_success = inv_or_est.update;
      raise "FreshBooks API has changed. Document could not be readied." unless update_success
    end
    pdf_file
  end

See more at: http://github.com/elc/freshbooks.rb/tree/master

Hirb: An Easy-to-Use View Framework for irb

hirb The Interactive Ruby Shell (irb) and the Rails console are great for interacting and experimenting with your ruby application code, but sometimes it’s hard to visualize the output. Gabriel Horner has come to the rescue with Hirb: a ‘mini view framework’ for irb which is designed to improve the default output to make it more human-readable.

Hirb does this by formatting console output according to its type, and paging if there’s more than a screenful to display. For example, Hirb will automatically display ActiveRecord model instances in a non-wrapping, table-like view.

irb>> Tag.last
+-----+-------------------------+-------------+
| id  | created_at              | description |
+-----+-------------------------+-------------+
| 907 | 2009-03-06 21:10:41 UTC | blah        |
+-----+-------------------------+-------------+
1 row in set

There’s also a helper provided which displays a collection of arrays or hashes as a tree. This might be useful for visualizing class inheritance trees, nested classes or relationships between ActiveRecord models (as this blog post describes).

In addition to the defaults you can specify your own reusable views, as the author explains in the documentation, leading you through an example of displaying hashes as YAML.

Hirb prints to the standard output by default, but you can configure it to write to anywhere you like, such as a log file.

The source code is on Github (or it can be installed as a gem), with documentation available on the author’s site. Hirb users are invited to share any views they have written by forking the Github repository and adding them into the project structure.

MongoMapper, The Rad Mongo Wrapper

In which I formally release MongoMapper, a high level wrapper similar to ActiveRecord, but for MongoDB.

MongoMapper
A few weeks ago, I wrote about Mongo and how awesome it is. Towards the end of the article (and in the slideshow) I mentioned MongoMapper, a project I’ve been working on.

Over the past few weeks my buddies at Squeejee and Collective Idea have started using MongoMapper and they’ve helped me squash a few bugs and add a few features.

Despite the fact that I would call it far from finished, I’ve decided to release it in hopes that people can start playing with it, finding bugs, adding features and submitting pull requests. The documentation is sparse to none, but there are plenty of tests and the code is pretty readable, I believe.

Installation

# from gemcutter
gem install mongo_mapper

Usage

So how do you use this thing? It’s pretty simple. MongoMapper uses a default connection from the Ruby driver. This means if you are using Mongo on the standard port and localhost, you don’t have to give it connection information. If you aren’t, you can do it like this:

MongoMapper.connection = Mongo::Connection.new('hostname')

Connection accepts any valid Mongo ruby driver connection. The only other setup you need to do is to tell MongoMapper what the default database is. This is pretty much the same as setting up the connection:

MongoMapper.database = 'mydatabasename'

These two operations only define the default connection and database information. Both of these can be overridden on a per model basis so that you can hook up to multiple databases on different servers.

Include Instead of Inherit

To create a new model, I went with the include pattern, instead of inheritance. In ActiveRecord, you would define a new model like this:

class Person < ActiveRecord::Base
end

In MongoMapper, you would do the following:

class Person
  include MongoMapper::Document
end

Just like ActiveRecord, this makes assumptions. It assumes you have a collection named people. Oh, and the good news is you don’t need a migration for it. The first time you try to create a person document, the collection will be created automatically. Heck yeah! I mentioned that you can override the default connection and database on a per document level. If you need to do that, it would look like this:

class Person
  include MongoMapper::Document

  connection Mongo::Connection.new('hostname')
  set_database_name 'otherdatabase'
end

Defining Keys

Each document is made up of keys. Keys are named and type-casted so you know your data is stored in the correct format. Lets fill out our Person document a bit.

class Person
  include MongoMapper::Document

  key :first_name, String
  key :last_name, String
  key :age, Integer
  key :born_at, Time
  key :active, Boolean
  key :fav_colors, Array
end

Now that we have defined our schema, we can create, update and delete documents.

person = Person.create({
  :first_name => 'John',
  :last_name => 'Nunemaker',
  :age => 27,
  :born_at => Time.mktime(1981, 11, 25, 2, 30),
  :active => true,
  :fav_colors => %w(red green blue)
})

person.first_name = 'Johnny'
person.save

person.destroy
# or you could do this to destroy
Person.destroy(person.id)

Looks pretty familiar, eh? Where it made sense, I tried to stay close to ActiveRecord in API.

Validations

But wait you say, how do I validate my data? Well, you can do it pretty much the same way as ActiveRecord.

class Person
  include MongoMapper::Document

  key :first_name, String
  key :last_name, String
  key :age, Integer
  key :born_at, Time
  key :active, Boolean
  key :fav_colors, Array

  validates_presence_of :first_name
  validates_presence_of :last_name
  validates_numericality_of :age
  # etc, etc
end

But, if you find that a bit tedious as I do, you can use some shortcuts that I’ve added in.

class Person
  include MongoMapper::Document

  key :first_name, String, :required => true
  key :last_name, String, :required => true
  key :age, Integer, :numeric => true
  key :born_at, Time
  key :active, Boolean
  key :fav_colors, Array
end

Most of the validations from Rails are supported. I still need to build in support for validates_uniqueness of and some of the options that rails supports might not be right now, but it is a good first pass.

Callbacks

Did you hear that? I swear I just heard someone whisper about callbacks. Umm, yeah, we got that too. The good news? I just used ActiveSupport’s callbacks so they are identical to Rails and most of Rails defined callbacks are supported such as before_save and the like.

Embedded Documents

So the cool thing about Mongo is that you can embed documents in other documents. Let’s say our person has multiple addresses. To handle that, we would create an embedded address document to go along with our person document.

class Address
  include MongoMapper::EmbeddedDocument

  key :address, String
  key :city,    String
  key :state,   String
  key :zip,     Integer
end

class Person
  include MongoMapper::Document

  many :addresses
end

Now we can add addresses to the person like so:

person = Person.new
person.addresses << Address.new(:city => 'South Bend', :state => 'IN')
person.addresses << Address.new(:city => 'Chicago', :state => 'IL')
person.save

Doing this actually saves the address right inside the person document. Yep, no joins. Yay! Cheers resound from the heavens! You can even query for documents based on these embedded documents. For example, if you wanted to find all people that are in the city Chicago, you could do this:

Person.all(:conditions => {'addresses.city' => 'Chicago'})

Finding Documents

The find API is very similar to AR as well. Below are a bunch of other examples:

Person.find(1)
Person.find(1,2,3,4)
Person.find(:first)
Person.first
Person.find(:last)
Person.last
Person.find(:all)
Person.all
Person.all(:last_name => 'Nunemaker', :order => 'first_name')

For more information about how to provide criteria to find, you can see the stuff covered in the finder options. If you need to, you can even throw custom mongo stuff into the mix and it just gets passed through to the mongo ruby driver (ie: $gt, $gte, $lt, $lte, etc.).

Conclusion

We take ActiveRecord for granted. It really has a lot of handy features and does a pretty good job at modeling our applications. I never realized how much it does, until I decided to create MongoMapper. That said, the experience has been fun thus far and I’m excited to see what people use it for.

There is a ton more I could talk about, but frankly, this article is long enough. Rest assured that I think Mongo is cool and that MongoMapper is headed in the right direction, but far from complete. I haven’t actually built anything with MongoMapper yet, but I will be soon. I’m sure that will lead to a lot of handy new features.

Any general discussion can happen in the comments below while they are open or over at the google group. If you find a bug or have a feature idea, create an issue at github.

Auto delta parent records in ThinkingSphinx

Auto updating sphinx delta on child record updates

Thinking Sphinx is quickly becoming the de-facto rails search plugin. In the past there have been a few other plugins that gained popularity and lost it almost as quickly by either being orphaned, outdated, etc. Thinking Sphinx has a clear path and a very involved/attentive maintainer.

Thinking Sphinx is quickly becoming the de-facto rails search plugin. In the past there have been a few other plugins that gained popularity and lost it almost as quickly by either being orphaned, outdated, etc. Thinking Sphinx has a clear path and a very involved/attentive maintainer.

The way sphinx does it’s “Live Updates” is through delta indexing. This allows indices to be added without rebuilding the master index. Thinking Sphinx handles new and updated records to be added to the delta through a couple of facilities, the one I will be focusing on is the delta boolean which is added to your index definition block like so:

Class UsedVehicle < ActiveRecord::Base
  define_index do
    indexes [manufacturer, model], :as => make_and_model
    indexes :trim_level
    indexes :year
    indexes :color
    indexes :condition
    indexes :price
    
    #index relations
    indexes option_package.options, :as => :options
    indexes accessories.package, :as => :accessory_package
    
    #this is to allow for delta index updating on record modification
    set_property :delta => true
  end
  
  ...
  
end

In the example above we’re indexing option_package.options and accessories.package which are ActiveRecord relations. Thinking Sphinx will update the parent UsedVehicle records in the delta when it sees them changed, through the ‘delta’ column on UsedVehicle, but what if you’re updating the child records? Simple:

Class OptionPackage < ActiveRecord::Base
  after_update :set_parent_delta
  
  def set_parent_delta
    self.used_vehicle.update_attributes(:delta => true)
  end

  ...

end

Now you’d want to do the same to the Accessory class to get that updating also. And it’s that simple.

Scraping Images from Twitpics

Recently, I’ve been scraping Images and videos from Twitter and one site that has not been too easy to grab pics from is Twitpics. Here’s a snippet of code that I’ve been using to grab the image from Twitpic with Hpricot:

require 'net/http'
require 'hpricot'

def rip_twitpic(url)
  begin
    code=url.match(/[\w]+$/).to_s
    unless code.blank?
      uri=URI.parse(url)
      resp=Net::HTTP.get_response(uri)
      html=Hpricot(resp.body)
      html.at("#photo-display")['src']
    end
  rescue Exception => e
    puts "Error extracting twitpic: #{e}"
    url
  end
end

Note: Thanks to Stephen Boisvert for showing my typo. That’s what I get for rushing something out and drinking too many cups of coffee.

RailsLab: Load Testing – Part 1

I’ve got another Scaling Rails screencast out today, this one the first of two episodes on learning about Load Testing.

Summary

In this first Load Testing Screencast we learn what exactly load testing is, why it’s useful, and learn how to properly use Apache Bench and httperf. These tools are very useful to gauge how your application handles under a heavy load.

Don’t forget to subscribe to the screencast RSS feed or grab it on ITunes to avoid missing any of these episodes. FYI, These videos look great on an iPhone / iPod if you want something to watch on the go.

RailsLab: Load Testing – Part 1

I’ve got another Scaling Rails screencast out today, this one the first of two episodes on learning about Load Testing.

Summary

In this first Load Testing Screencast we learn what exactly load testing is, why it’s useful, and learn how to properly use Apache Bench and httperf. These tools are very useful to gauge how your application handles under a heavy load.

Don’t forget to subscribe to the screencast RSS feed or grab it on ITunes to avoid missing any of these episodes. FYI, These videos look great on an iPhone / iPod if you want something to watch on the go.

Coworking Visas: Offices Without Borders

You_talking

Listen up, Señor T is talking to you. If you have ever tried to spend 8 hours working from a coffee shop, then I don’t have to tell you that it’s not all that it’s cracked up to be. Yes, its a fun dynamic working environment, where people will make you coffee and tasty snacks. However, spotty internet connections, loud music, chatty patrons and lack of power outlets get old quick. But for a cybernomad like me, plopping down a monitor on a desk just isn’t an option.

Shared Workspaces

In recent years, shared community orientated workspaces have been growing in numbers. Places like Souk, which we jokingly refer to as the ELC Portland office, are great places to drop in and work. They have flexible memberships and sport all the accommodations of a regular office (except a boss). I am currently at Office Nomads in Seattle and they even have a kegarator, a 48 inch TV and people doing Yoga.
Officenomads

Coworking Visas

Obama_sez

But you still don’t want to be stuck in the same city in the same shared office, because a shared office is still an office. Enter the Coworking Visa, which is a network of shared workspaces like Souk and Office Nomads that allow you to float between them if you have a membership at one location. This isn’t a small network either. They are in most major and some not so major US cities and 13 countries around the world, including Buenos Aires where I spent the last month. Anyways, its totally amazing and I encourage you all to pick up your computer and wander with it. Sorry the pictures are so bad, I broke my camera.

Egginhole

Yes that is egg-in-a-pancake-hole, I had it for breakfast.

Rails Envy Podcast – Episode #084: 06/24/2009

Episode 84. This week Nathan Bibler joins me to talk about bug fixes of bug fixes, new libraries, video podcasts, Duke Nukem, and Zelda.

Subscribe via iTunes – iTunes only link.
Download the podcast ~11:00 mins MP3.
Subscribe to feed via RSS by copying the link to your RSS Reader



Runway is a GTD-style action management web application made by geeks for geeks. Created by the folks at Cogent, try a free demo at http://www.runwayapp.com.

Sponsored by New Relic
NewRelic not only provides rails performance monitoring with RPM, but they also produce Rails Lab, a website dedicated to advice on tuning and optimizing Rails apps.

Show Notes

ReCSS – AJAX friendly CSS testing

Back in the days when the web didn’t yet have a version number, David from dojotoolkit.org came up with a neat solution to reload your css without the need of reloading your page: ReCSS.

It’s just a simple bookmarklet that walks through all linked stylesheets and reloads them. This omits page reloads in order to test your CSS changes, very helpful for AJAX heavy sites. Here is what the code looks like:

javascript: void(function() {
    var i, a, s;
    a = document.getElementsByTagName('link');
    for (i = 0; i < a.length; i++) {
        s = a[i];
        if (s.rel.toLowerCase().indexOf('stylesheet') >= 0 && s.href) {
            var h = s.href.replace(/(&|%5C?)forceReload=\d+/, '');
            s.href = h + (h.indexOf('?') >= 0 ? '&': '?') + 'forceReload=' + (new Date().valueOf())
        }
    }
})();

This is one of the small things that makes my life easier, and I want to make sure that it does the same for you. Drag the following link to your Bookmarks toolbar and become a CSS rockstar: ReCSS

Rails Envy Podcast – Episode #084: 06/24/2009

Episode 84. This week Nathan Bibler joins me to talk about bug fixes of bug fixes, new libraries, video podcasts, Duke Nukem, and Zelda.

Subscribe via iTunes – iTunes only link.

Download the podcast ~11:00 mins MP3.

Subscribe to feed via RSS by copying the link to your RSS Reader


Runway is a GTD-style action management web application made by geeks for geeks. Created by the folks at Cogent, try a free demo at http://www.runwayapp.com.

Sponsored by New Relic
NewRelic not only provides rails performance monitoring with RPM, but they also produce Rails Lab, a website dedicated to advice on tuning and optimizing Rails apps.

Show Notes

Modular Java; iPhone interview; twitter news and a surprise

Modular Java in print, the Radical Career Success in a Down Economy webcast, iPhone SDK interview, Twitter features, and a surprise.

Launching Rails projects, an open call for lessons learned

I’m working on my presentation for Rails Underground and was hoping to solicit a few tips from other people in the industry.

Have you launched a Ruby on Rails application recently? Are there some things that you wish you had known beforehand?


<p>Mind sharing? You can email me with your story at  <a href="mailto:robby+launchstory@planetargon.com">robby+launchstory@planetargon.com</a>. I&#8217;ll let you know if your tip gets used in the presentation and please indicate if you&#8217;d be okay with me posting your tip in a future blog post.</p><div class="feedflare">