Posts tagged ruby on rails

Sextant: A Gem to Help you Find your Routes

News flash, writing a Rails app without knowing your routes is pretty much impossible, and this just in $ rake routes takes forever [1] to run. So how can we build a Rails site with a minimum of time and a maximum of awesome? You can use the recently released Sextant Gem [2] to generate routes in your Rails app.

As it turns out if you benchmark the code in $ rake routes it is reasonably fast, the slow part comes from having to initialize the app environment every time it’s run. So lets take some of that code and put it in your already initialized web app. What you get is a whole lot of awesome in a tiny package. Next time you want to see your routes, just visit /rails/routes in your browser if you’ve got sextant installed, and you’ll see your routes in no time.

Sextant Output

To install add this to your Gemfile:

gem 'sextant' 

Then run bundle install and you’re good to go. Start your server and visit /rails/routes

This in-browser information is local only. If you like Sextant tell your friends, and tell me @schneems

  • [1] Forever is measured in seconds
  • [2] Sextant is an old device for navigating. It can help you find your route on a long journey.

You got NoSQL in my Postgres! Using Hstore in Rails

Heroku just announced their support of hstore in their dedicated Postgres 9.1 instances. Hstore is a schema less key value store inside of PostgreSQL that allows us to store data like hashes directly inside of a column. It’s great for when you don’t know exactly what types of attributes you need to store on a model, or if you need to support many different attributes for the same model.

Update: You can now use Hstore with development databases on Heroku

A good example is storing attributes for a Product model. We might start out only selling books, which have an author, number of pages, but then transition over to selling laptops which have cpu speed and display resolution. Using Hstore allows us to easily store all these values without having to make a bunch mostly blank columns.

To get started with Rails and hstore you can watch the screencast below or visit the hstore example app running on Heroku.

More on Hstore

Hstore in Rails functions much like serializing hashes, except that we can query our data much faster since hstore is a native data type. It is supported natively in Rails 4, but until then we’ll need to use the activerecord-postgres-hstore gem.

Getting Started

You will need a version of PostgreSQL locally that supports the hstore extension. I recommend installing postgres using homebrew on OS X. Once you’ve done that you can enable hstore usage by running this in Postgres

CREATE EXTENSION hstore;

You can put this in a migration if you prefer

class SetupHstore < ActiveRecord::Migration
  def self.up
    execute "CREATE EXTENSION hstore"
  end

  def self.down
    execute "DROP EXTENSION hstore"
  end
end

Once that is done you will need to create a column with a type of hstore, here we are giving our Product model a column called data with hstore type.

class CreateProducts < ActiveRecord::Migration
  def change
    create_table :products do |t|
      t.string  :name
      t.hstore  :data
      t.timestamps
    end
  end
end

Once we’ve done that we can now store any type of attributes in the data column.

Product.create(:name => "Geek Love: A Novel", :data => {'author' => 'Katherine Dunn', 'pages' => 368, 'category' => 'fiction'})
Product.last.data['category']  # => 'fiction'

Querying

Not only does hstore allow us to store arbitrary keys and values it allows us to quickly query them.

  # Find all products that have a key of 'author' in data
  Product.where("data ? :key", :key => 'author')

  # Find all products that have a 'pages' and '368' key value pair in data
  Product.where("data @> (:key => :value)", :key => 'pages', :value => '368')

  # Find all products that don't have a key value pair 'pages' and '999' in data
  Product.where("not data @> (:key => :value)", :key => 'pages', :value => '999')

  # Find all products having key 'author' and value like 'ba' in data
  Product.where("data -> :key LIKE :value",     :key => 'author, :value => "%Kat%")

More information available in the Postgres hstore docs. Though like a normal column if you query it frequently, you can get even more speed by adding an index. You can do this using one of two indexes that also speed up full text searches. They’re GiST (Generalized Search Tree) or GIN (Generalized Inverted iNdex). Which sill speed up queries using the @> and ? postgres operators.

class Index < ActiveRecord::Migration
  def up
    execute "CREATE INDEX products_gin_data ON products USING GIN(data)"
  end

  def down
    execute "DROP INDEX products_gin_data"
  end
end

Use It

Try out the hstore example app, clone the Github repo, and let me know what cool things you build on twitter @schneems.

Thanks

Special thanks to Aaron Patterson and Joel Hoffman for their work with hstore & Rails4, to the team at Softa for writing this gem, & and the team at Heroku for their contributions to Postgres, and supporting this feature.

Speed up Capybara Tests with Devise

All good developers should write tests, and anyone with a high stake in a web app should write acceptance tests. Acceptance tests use a web driver like Capybara to test the full functionality of your web app by interacting directly with view elements the same way a user would (clicking links, filling out forms, etc.)

My only problem with acceptance tests is that they can be a bit slow, so i’m always looking for ways to speed mine up. One of my pain points is since everything is done via manual interaction with a headless website, any test requiring a logged in user (most of them) also requires that before it is run, Capybara must log the user in by visiting the sign in path and entering valid credentials. While I still think manual sign in should be tested, it doesn’t need to be tested every single time we run another test.

If you’re doing authentication with Devise to speed things up a bit we can stub out a logged in user with Warden’s built in test helpers.

It works like this when you’re running a non-acceptance test we want to use Devise’s sign_in helper since we have direct access to the request object (not available during capybara/acceptance tests). All other times we want to use Warden’s login_as method.

Here is an example of as_userand as_visitor helpers that do just that:

I then needed to call Warden.test_reset! after each test to ensure correct functionality

RSpec.configure do |config|
  config.after(:each) { Warden.test_reset! }
end

Then in my tests (shown here with capybara/rspec, I can simply log in a user like this:

It’s that simple. With a few lines of code I was able to speed up my tests and keep all expected behavior. For more details on how this works, you can go to the wiki page I created: https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara . Good luck and happy testing!

Keep your Rails Project Sane

We’ve all been there, we start a new project with grand hopes and aspirations. But soon enough our project turns into one big ball of mud. In this presentation I talk about some common mistakes in Rails and how to keep your project Sane.

I gave this presentation at Austin On Rails and it was filmed by Austin Tech Videos.

Rails 3 Beginner to Builder 2011 Week 6 with Ethan Waldo

 

This is part 6 of my Rails 3: Beginner to Builder series. http://schneems.com/beginner-to-builder-2011 with special guest speaker Ethan Waldo

Assignment before next week (Week 7): Chapters 15, 16, 17

We will NOT be meeting on July 21st, due to a conflict with Austin.rb (which i highly recommend you attend). Its a going to be a great meeting, and I hope to see many of you there. 

Rails 3 Beginner to Builder 2011 Week 6 from richard schneeman on Vimeo.

Rails 3 Beginner to Builder 2011 Week 6 View more presentations from Richard Schneeman.

  Topics:

    - Email in Rails

    - Background Tasks

    - modules

    - Observers & Callbacks

    - Internationalization & Localization

    - I18n & L10n


Rails 3 Beginner to Builder 2011 Week 5

This is part 5 of my Rails 3: Beginner to Builder series. http://schneems.com/beginner-to-builder-2011

Assignment before next week (Week 6): Chapters 12, 13, & 14



Rails 3 Beginner to Builder 2011 Week 5 from richard schneeman on Vimeo.

Rails 3 Beginner to Builder 2011 Week 5 View more

presentations from Richard Schneeman

  Topics:

    - Data Flow

      - View to Controller

      - controller to view

    - Routes

    - Params

    - Authenticating Users

    - Cryptographic Hashes (cool huh)

    - Authlogic

Rails 3 Beginner to Builder 2011 Week 2

This is part 2 of my Rails 3: Beginner to Builder series. http://schneems.com/beginner-to-builder-2011

Assignment before Week 3: Chapters 6 & 7

Video

Rails 3 Beginner to Builder 2011 Week 2 from richard schneeman on Vimeo.

Slides

Rails 3 Beginner to Builder 2011 Week 2 View more presentations from Richard Schneeman.

Topics:

  - Rails

    - Code Generation

    - Migrations

    - Scaffolding

    - Validation

    - Testing (AutoTest)

  - Ruby

    - Hashes

    - class versus instances

Rails 3 Beginner to Builder 2011 Week 1

Rails 3 Beginner to Builder 2011

This is part 1 of my Rails 3: Beginner to Builder series. http://schneems.com/beginner-to-builder-2011

If you’re looking to learn Rails 3.0.0 and you’ve got no experience, then you’re in the right place. This class taught at the University of Texas is an 8 week long series of one hour classes, taught by yours truly. We’re going to be doing course work out of the Agile Web Development with Rails version 4 book, so if you’d like to follow along at home, you’ll need to get a copy. Below is the video of the class presentation as well as a copy of the slides.

If you have technical questions and don’t have time to wait for class I highly encourage you to find chat room on IRC, or to ask a question on Stack Overflow. I also recommend attending a local Rails user groups such as Austin on Rails. Coding is a social sport, so the quicker you can join the community, the better. 

Assignment before starting this week: Chapters 1 & 2

Assignment before week 2: Chapters 3, 4 & 5

Video

Untitled from richard schneeman on Vimeo.

Presentation

Rails 3 Beginner to Builder 2011 Week 1 View more presentations from Richard Schneeman

A word of warning: Different versions of rails can be drastically different, this is a course on rails 3.0. It does not cover Rails 2.X and will not cover any features introduced in 3.1 or later.

Week 1 Topics:

  -Rails

    - Intro to Rails

    - Rails Architecture

    - MVC (Model View Controller)

    - ORM (Object Relational Mapping)

    - RESTful (REpresentational STate)

  - Ruby

    - Strings

    - Symbols

    - Arrays

    - Hashes

  - Work Environment

    - Verion Control

    - Ruby Gems

    - Bundler

    - RVM

    - Tests