Learn About Rails 3’s Fantastic New Router

Rizwan Reza recently wrote a post about many of the new features in Rails 3’s router. The changes are significant and, in one fell swoop, moot many of the routing plugins people have written over the years.

Check it out at http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3

Stanza bookshelf, iPad, Test-Driven Development for Embedded C

Download your own books from Stanza bookshelf, iPad announcement, Test-Driven Development for Embedded C now in beta

SSL Hostname Add-on Public Beta

Ever since we launched the current IP-based solution at $100/month in response to customer demand, we have been pursuing a cheaper and more elegant solution for SSL with custom certificates on Heroku.

Today, we’re happy to announce the public beta of a new SSL add-on that accomplishes this goal. It’s called ssl:hostname, and is priced at $20/month. This new add-on will allow you enable SSL traffic to your application on any subdomain, such as www.mydomain.com or secure.mydomain.com, using your own SSL certificate. Note that this is a paid beta, and you will be charged for using the add-on through the beta period.

Full docs are available here. You can install it via the heroku gem, or directly from the Add-ons Catalog.

Because Gem Names Are Like Domains in the 90’s

One of my favorite parts of every new gem is naming it. The other day, when I was trying to name joint, it occurred to me that I should always check if a gem name is available before I create my project. I did a quick search on RubyGems and discovered it was available.

Last night, I decided I should whip together a tiny gem that allows you to issue a whois command to see if a gem name is taken. Why leave the command line, eh?

Installation

gem install gemwhois

This adds the whois command to gem. Which means usage is pretty fun.

Usage

$ gem whois httparty

   gem name: httparty
     owners: John Nunemaker, Sandro Turriate
       info: Makes http fun! Also, makes consuming restful web services dead easy.
    version: 0.5.2
  downloads: 40714
  
$ gem whois somenonexistantgem

  Gem not found. It will be mine. Oh yes. It will be mine. *sinister laugh*

If the gem is found, you will see some details about the project (maybe you can convince them to hand over rights if they are squatting). If the gem is not found, you will receive a creepy message in the same vein as the RubyGems 404 page.

The Fun Parts

The fun part of this gem was recently I noticed that other gems have been adding commands to the gem command. I thought that was interesting so I did a bit of research. I knew that both gemedit and gemcutter added commands so I downloaded both from Github and began to peruse the source. Turns out it is quite easy.

First, you have to have a rubygems_plugin.rb file in your gems lib directory. This is mostly ripped from gemcutter:

if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.3.6')
  require File.join(File.dirname(__FILE__), 'gemwhois')
end

Next, you have to create a command. At the time of this post, here is the entirety of the whois command:

require 'rubygems/gemcutter_utilities'

class Gem::Commands::WhoisCommand < Gem::Command
  include Gem::GemcutterUtilities

  def description
    'Perform a whois lookup based on a gem name so you can see if it is available or not'
  end

  def arguments
    "GEM       name of gem"
  end

  def usage
    "#{program_name} GEM"
  end

  def initialize
    super 'whois', description
  end

  def execute
    whois get_one_gem_name
  end

  def whois(gem_name)
    response = rubygems_api_request(:get, "api/v1/gems/#{gem_name}.json") do |request|
      request.set_form_data("gem_name" => gem_name)
    end

    with_response(response) do |resp|
      json = Crack::JSON.parse(resp.body)
      puts <<-STR.unindent

        gem name: #{json['name']}
          owners: #{json['authors']}
            info: #{json['info']}
         version: #{json['version']}
       downloads: #{json['downloads']}

      STR
    end
  end

  def with_response(resp)
    case resp
    when Net::HTTPSuccess
      block_given? ? yield(resp) : say(resp.body)
    else
      if resp.body == 'This rubygem could not be found.'
        puts '','Gem not found. It will be mine. Oh yes. It will be mine. *sinister laugh*',''
      else
        say resp.body
      end
    end
  end
end

The important part is inheriting from Gem::Command. Be sure to require 'rubygems/command_manager' at some point as well. Once you have the rubygems_plugin file and a command created, you simple register the command:

Gem::CommandManager.instance.register_command(:whois)

The comments and code in RubyGems itself is pretty helpful if you are curious about what you can do.

Testing

The trickier part was testing the command. Obviously, building the gem from gemspec and installing over and over does not a happy tester make. I did a bit of research and found the following testing output helpers and the unindent gem:

module Helpers
  module Output
    def assert_output(expected, &block)
      keep_stdout do |stdout|
        block.call
        if expected.is_a?(Regexp)
          assert_match expected, stdout.string
        else
          assert_equal expected.to_s, stdout.string
        end
      end
    end

    def keep_stdout(&block)
      begin
        orig_stream, $stdout = $stdout, StringIO.new
        block.call($stdout)
      ensure
        s, $stdout = $stdout.string, orig_stream
        s
      end
    end
  end
end

With these little helpers, it was quite easy to setup the command and run it in an automated way:

require 'helper'

class TestGemwhois < Test::Unit::TestCase
  context 'Whois for found gem' do
    setup do
      @gem = 'httparty'
      stub_gem(@gem)
      @command = Gem::Commands::WhoisCommand.new
      @command.handle_options([@gem])
    end

    should "work" do
      output = <<-STR.unindent

        gem name: httparty
          owners: John Nunemaker, Sandro Turriate
            info: Makes http fun! Also, makes consuming restful web services dead easy.
         version: 0.5.2
       downloads: 40707

      STR
      assert_output(output) { @command.execute }
    end
  end
  
  context "Whois for missing gem" do
    setup do
      @gem = 'missing'
      stub_gem(@gem, :status => ["404", "Not Found"])
      @command = Gem::Commands::WhoisCommand.new
      @command.handle_options([@gem])
    end

    should "work" do
      output = <<-STR.unindent

        Gem not found. It will be mine. Oh yes. It will be mine. *sinister laugh*

      STR
      assert_output(output) { @command.execute }
    end
  end
end

The only other piece of the puzzle was using FakeWeb to stub the http responses for the found and missing gems. You can see more on that in the test helper file.

Conclusion

At any rate, the gem is pretty tiny and possibly useless to others, but it was fun. Gave me a chance to play around with testing STDOUT and creating RubyGem commands. Plus, now I know if the gem name I want is available in just a few keystrokes.

Ruby Hero Awards 2010

Ruby Heroes

It’s that time again to take a moment to think about those people who have impacted Ruby community but have not received the recognition they deserve. We have given away twelve awards in the past two years at Railsconf, and this year we are preparing to give away six more.

But we need your help.

So, if you know someone who has contributed to our community this year please take a moment to show some gratitude by nominating them on RubyHeroes.com. A month from now the Ruby Heroes from last year will look at the nominations and decide who should receive the awards (this way there’s no popularity contest). However, your nominations do matter, so please take a moment and spread the gratitude.

The winners will be announced live on stage at Railsconf 2010, and posted here shortly there after.

#207 Syntax Highlighting

Here I talk about three popular choices for syntax highlighting in Rails: CodeRay, Ultraviolet and Pygments.

#207 Syntax Highlighting

Here I talk about three popular choices for syntax highlighting in Rails: CodeRay, Ultraviolet and Pygments.

A Nunemaker Joint

Since The Changelog has already scooped me (darn those guys are fast), I figured I should post something here as well. Last December I posted Getting a Grip on GridFS. Basically, I liked what Grip was doing, but made a few tweaks. Grip’s development has continued, but it is headed down a bit different path, so I thought it might be confusing to keep my fork named the same.

Today, I did some more work on the project and now that it is unrecognizable when compared to Grip, I renamed it to Joint. Yes, I realize that I now have gems named crack and joint. Joint is a tiny piece of code that joins MongoMapper and the new Ruby GridFS API.

Usage

What I love about joint is its simplicity. Simply declare the attachment and you are good to go.

class Asset
  include MongoMapper::Document
  plugin Joint # add the plugin

  attachment :file # declare an attachment named image
end

With that simple declaration, you get #file and #file= instance methods and several keys (file_id, file_name, file_type, and file_size). The #file instance method returns a simple proxy to make the API a bit prettier and sends all other calls on the proxy to the GridIO instance.

asset = Asset.create(:file => params[:file])
asset.file.id   # GridFS Object Id
asset.file.name # file name
asset.file.type # mime type as determined by wand gem
asset.file.size # size in bytes

There is no limit to the number of attachments, but each attachment uses 4 keys so I would not add more than one or two (more is a sign you are doing something wrong). As mentioned in the comment above, it uses my wand project to determine the mime type.

For those that are not familiar with wand (as I have not posted here about it), it first attempts to determine the mime type using the mime-types gem. If that fails to returning anything, it drops down to the unix file command.

What It Does Not Do

Anything else. All joint handles is assigning a file and storing it in GridFS. It doesn’t do versions, resizing, etc. For this type of stuff, I would recommend imagery with some HTTP caching (varnish, et el.) sitting in front of it.

I can certainly see having some triggers (callbacks) at some point such as after jointed or something for when you do want to do post processing. I’ll leave that for a rainy day though.

James Edward Gray II – Ruby on Rails Podcast

Ruby veteran James Edward Gray II talks about Ruby daemons, TextMate 2, and Rails 3.

Also Mentioned

James Edward Gray II – Ruby on Rails Podcast

Ruby veteran James Edward Gray II talks about Ruby daemons, TextMate 2, and Rails 3.

Also Mentioned

Blocking Amazon advertisements

Dealing with advertisements is a part of life, from watching TV to running free apps on the iPhone.  It’s made Google the envy of all tech companies.  Fortunately for those who want to minimize exposure to them, there are some options such as DVR for the TV and Adblock Plus for Firefox.  I haven’t read […]

Supermodel: Simple ActiveModel-Powered In-Memory Models

Supermodel is a new library by Alex Maccaw that uses the Rails 3.0 ActiveModel library to provide ActiveRecord-esque in-memory “database” storage in Ruby.

Supermodel is best demonstrated with a basic example:

require 'supermodel'

class Person < SuperModel::Base; end

a = Person.new( :name => "Jim" )
a.save

Person.find_by_name('Jim') # => #<Person>
Person.all # => [#<Person>]

This is just the start! Out of the box, Supermodel supports validations, callbacks, observers, dirty change tracking, and serialization. It also allows you, with only a little magic, to go beyond ephemeral memory-only structures and marshall your SuperModel-based objects to disk or even to a Redis store.

A more complex example that includes randomly generated IDs and validations:

require 'supermodel'

class Person < SuperModel::Base
  include SuperModel::RandomID
  attributes :name
  validates_presence_of :name
end

a = Person.new
a.valid? # => false
a.name = "Jim"
a.valid? # => true
a.save
a.id # => "6481a4fcd834e567836587c6da"

It’s early days for Supermodel, but I can see it becoming a big deal for Rubyists away from the Rails stack. The gemified version doesn’t have support for relationships yet, but the edge version on GitHub has early support for belongs_to and has_many included.Alex has written the code in a well structured way and creating modules or subclasses to add support for interacting with other backends (such as, say, Tokyo Cabinet) doesn’t look like it’d be too hard.

Supermodel shows a lot of promise and is what I was originally hoping ActiveModel was going to be. It provides just the right level of abstraction and separation from the database, but without losing the goodness we came to enjoy from ActiveRecord over the past few years.

UI.fail

Every now and then I come across a piece of software with a “feature” that just irks me. I have been using Adobe Media Player to play my media clips, as an alternative to VLC. But after having played quite a few, I wanted to clear out the list of personal videos. […]

ELC in Edinburgh Sponsoring Scottish Ruby Conference

Find ELC at the Scottish Ruby Conference in Edinburgh. The weather may be poor but the people and town are fantastic. We encourage you to find us for hack tomorrow afternoon or a pint in the evening.

#111: State machine

Jason and Dan bring you the latest (and most interesting) Ruby news.

Genius Pool
Check out Genius Pool to post a job on the Ruby Show.

Links for this episode:

Sinatra 1.0 Released

Sinatra is one of our favorite frameworks at Heroku. Many of our apps use Sinatra, and Blake even works here. All this means we’re extremely excited to congratulate the Sinatra team on the 1.0 release!

You can use Sinatra 1.0 today on Heroku. It works with both the Aspen and Bamboo stacks. Simply add the gem to your .gems file, git push, and you’ll be running Sinatra 1.0!

Rails and the Enterprise

If you have been in the Rails community for a little while, you have more than likely noticed the love/hate relationship that is entertained by the community vis-à-vis the Enterprise.
Some people hate the enterprise and publicly tell it to go f*ck itself (49:39), on the other hand, these same people are also proud to mention that some major players in the industry use Ruby and Rails.

The truth is that even though Ruby and Rails could still be more Enterprise ready, it is already a great combo that big corporations can start using today, and lots of then already do! Let’s look at the state of Rails and the Enterprise.

So where are we at?

  • First things first, Rails was not designed for the enterprise or for the enterprise’s needs. It was extracted from a successful startup project and has grown with the contribution of people using Rails daily. But Rails is also based on Ruby which became very popular and started to be used in different places, including NASA, for instance.
  • 37signals still does NOT need “Enterprise features” and therefore don’t expect any 37signals engineers to write an Oracle Adapter or a SOAP layer for ActiveResource and push for their adoption.
  • Rails is far more than a framework used by 37signals. It is an Open Source project with code being contributed daily by people on other projects. Most of the code does not directly benefit 37signals.
  • The Enterprise is evolving: economic crisis, a new generation of developers, new management, insane deadlines. Ruby and Rails have quickly become very attractive for the Enterprise and having big companies acting as startups is often something a lot of managers dream of. As a matter of fact, here is a quote from Sony Computer Entertainment America’s President & CEO, Jack Tretton: “Be like a multi-billion dollar company on the outside, and act like a startup on the inside”. This change has taken a while because the Enterprise is a big mammoth (or insert another of your favorite gigantic, slow-starting animal here), but it’s happening.
  • Communication with/in big companies is not as straight forward as when dealing with startups who need/thrive for the outside attention and who don’t have all the red tape of a PR department, etc. Here is a simple example: I work for Sony Playstation. My job description mentioned Redis, MongoDB, EventMachine and many other technologies I did not know Sony was using in production. I did not realize that my default production stack would be built on Ruby 1.9. Communicating when you’re a part of a big company is more challenging than when you are a team of 5 engineers working on a cool project, and therefore a lot of people don’t know what technologies are being used by Company X or Company Y.
  • Rails is used by lots of big companies. It might not be obvious and you might have to look at the job offers but people like AT&T, Sony and many others are always looking for talented Ruby developers. And, even though Java and .NET are still ruling the Enterprise kingdom, dynamic languages are slowly but surely catching up. Rubyists are climbing the social ladder and are now in positions to push the language they love.

Understanding the Enterprise’s needs

It’s kind of hard to define “the Enterprise’s needs”, however I can testify that the needs and requirements of a so called “Enterprise app” are slightly different than those encountered when you work on a startup app.

What the Enterprise needs/wants:

  • reliability
  • support
  • performance
  • advantage over the competition
  • integration and transition path

Reliability

I think that it was proven many many times that Rails scales and can be very reliable as long as you know what you are doing. We are not talking anymore about a buzz framework that just got realized and that cool kids play with but rather, a stable platform used by some of the most popular web applications out there.

Support

This point is something the Rails community can be proud of. We have lots of forums, blogs, books, local meetings, conferences… Yes, Rails is OpenSource and you can’t buy yearly support from the core team but you will find all the help you need out there. (If you can’t, feel free to contact me and I’ll direct you to people who can help, and if you are new to Rails, take a look at http://railsbridge.org/)

Performance

Based on my own experience, the level of performance we have using Ruby and Rails is more than enough for the Enterprise world. This is especially true with Ruby 1.9 greatly improving performance and Rails3 optimizations.
If you really need part of your code to run as fast as C code, writing a C extension for Ruby is actually quite easy and will solve your speed issues.

Advantage over the competition

Rails comes with certain ways to do things, conventions that will get you up and running in much less time.
Ruby as a language is natural, intuitive and easy to maintain. By choosing the right tools for your project, you will definitely be able to get more done in less time and increase your business value faster. Let’s not forget the strong value of testing in the community that will push your team to write tested code and more than likely improve the overall code quality of your products.

Integration and transition path

This is probably the part that is the most challenging when you live in the Enterprise and look into using Ruby & Rails.
I was recently talking to someone from Google who used to do a lot of Ruby before joining the Mountain View-based company. We were talking about how he loves Ruby but had such a hard time integrating with existing Enterprise solutions. He mentioned how he got frustrated by the lack of great XML tools, bad/complicated SOAP libraries and a few others I can’t remember. The truth is that when my friend was using Ruby this all was true. REXML and soap4r are useful but might not perform that well. Luckily as the community has grown, new tools have come up and today Nokogiri (developed and maintained by AT&T engineer’s Aaron Patterson) can easily be used instead of REXML and many libraries are known to be better than soap4r such as savon, handsoap and others.
The other good news is that major IT companies such as Apple, Microsoft and Sun(RIP) have adopted Ruby and you can now write your code in Ruby and use native libraries from other languages such as Java, .NET or Objective-C.
The transition path can be done smoothly without having to commit to a total rewrite.

Database-wise, Oracle is still a viable option for Rails developers thanks to the Oracle ActiveRecord adapter (by R.Simanovskis). Note that your DBA might curse you for not doing optimized queries using bind variables and all the Oracle Magic spells, in which case you can use Sequel, a great ORM supporting Oracle, and some of its unique features.

Deployment-wise, you can deploy on IIS, Tomcat, Glassfish, Apache, Nginx, or almost anything mainstream you are already using. Using Passenger, deployment is as easy as deploying a PHP app and you also get a series of great tools such as Capistrano, Vlad etc…

So basically, thanks to passionate Rubyists working ‘for the man’ such as Aaron Patterson, Raimonds Simanovskis and others, using Ruby in the Enterprise is much much easier. Ruby and Rails were not initially designed with the Enterprise in mind but with time, the integration has become smoother and both parties can now enjoy reciprocal benefits.

#110: Unmentionable

In this episode, Jason and Dan bring you the latest news and discuss gem naming in the Ruby community.

Red Dirt Ruby Conf
Red Dirt Ruby Conf is a unique two-day conference that provides focused, up-to-date
content and related training in four of the most important areas of
active development in Ruby. Oklahoma City, May 6-7th, 2010.


Links for this episode:

Seven Languages in Seven Weeks, now in beta

Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages by Bruce Tate now in beta

Ruby Summer of Code

Rails participated in Google’s summer of code program for the first time last year. We got four great projects and three long-term contributors from the effort, including Josh Peek and José Valim, who’ve both joined Rails core, and Emilio Tagua, who revitalized Arel and integrated it with Active Record.

We applied again this year but didn’t make the cut, so we moped for a day then thought, why not make this happen ourselves. So here we are kicking off the first Ruby summer of code together with Engine Yard and Ruby Central.

Head over to rubysoc.org to get started and start following @rubysoc for news.

We’re following Google’s example closely:

  • students are paid a $5000 stipend to work full-time during their summer break
  • a group of Ruby gurus volunteer their time as mentors
  • mentors vote on student proposals based on usefulness, benefit to the Ruby community, and history of motivated open source contribution

We’re looking for full- and half-summer sponsors as well as individual donations. We’ll fund as many students as we can. Donate this week and our own <s>Aaron aka tenderlove will match it!</s> Aaron tapped out, you dogs 🙂 Thanks Aaron! Now Chad and Kelly Fowler are matching! Donate now!

Ruby gurus, consider mentoring a student this summer. Volunteering to guide the next generation of Ruby developers is a challenging and rewarding effort.

Students: start your engines! Check out our ideas list and start brainstorming. Applications begin on April 5!