Alter Column the Missing Migration Method for ActiveRecord

Changing many columns is not so easy, because change_column forces you to enter all attributes you want (default,limit,null…) again.
So to make less errors we just alter the attributes we want to change and leave the rest alone.

Install

#Inside your migration
def self.alter_column(table,column,text)
  execute("ALTER TABLE #{quote_table_name(table)} ALTER #{quote_column_name(column)} #{text}")
end

Usage

# to set the default to nil, without remembering all the other 
# stuff change_column needs
alter_column(:users,:name,"DROP DEFAULT")

So thats very basic, but i hope it helps anyway 🙂

More Cucumber Common Steps and Love

You just have to love this “syntax” 😀
Story

#features/discussion.feature
Scenario: I add to an discussion
    Given I am logged in
    And a "Discussion" exists for "Festival" "1"
    And I am on "Festival" "1"
    When I fill in "Text" with "Halloo"
    And I press "Send"
    Then I should be on "Festival" "1"
    And I should see "Halloo"

Steps

#features/step_definitions/common_steps.rb 
# On page/record
Given /^I am on "([^"]*)"$/ do |path|
  visit path
end

Then /^I should be on "([^"]*)"$/ do |path|
  current_path.should == path
end

Given /^I am on "([^"]*)" "([^"]*)"$/ do |model,number|
  visit polymorphic_path(record_from_strings(model,number))
end

Then /^I should be on "([^"]*)" "([^"]*)"$/ do |model,number|
   current_path.should == polymorphic_path(record_from_strings(model,number))
end

# Existing
Given /^a "([^"]*)" exists for "([^"]*)" "([^"]*)"$/ do |associated,model,number|
  record = record_from_strings(model,number)
  record.send(associated.underscore+'=',valid(associated))
  record.save!
end


# Login
Then /^I should be logged in$/ do
  should be_logged_in
end

Given /^I am logged in$/ do
  visit 'login'
  fill_in 'email', :with=>'quentin@example.com'
  fill_in 'password', :with=>'test'
  click_button 'Login'
end


# Support
def current_path
  response.request.request_uri
end

def record_from_strings(model,number)
  model.constantize.find(:first,:offset=>number.to_i-1)
end

env.rb

#features/support/env.rb
#load all fixtures
include AuthenticatedTestHelper #restful_authentification
include ValidAttributes #http://github.com/grosser/valid_attributes

Getting Started with Cucumber on Ubuntu

I finally found some time to mess with cucumber, its pretty nice but has some edges and quircks… but for now i like it 🙂

Install
This was rather hard… (these libraries and frex should not be necessary for mac)

sudo apt-get install libxslt1-dev libxml2-dev racc
sudo gem install aaronp-frex brynary-webrat
sudo gem install cucumber
./script/generate cucumber
rake features

First story

#features/signup.feature
Feature: Signup
  Scenario: A new user comes to the page and wants to register.
    Given I am on "/"
    When I click "register"
    And I fill in "user[name]" with "Michael G"
    And I fill in "Email" with "test@test.de"
    And I fill in "Password" with "test"
    And I fill in "Password confirmation" with "test"
    And I press "Register for the free basic account"
    Then I should be on "/"
    And I should be logged in
    And I should see a flash about "activation"

Environment setup

#append to features/support/env.rb
#load all fixtures -- https://pragmatig.wordpress.com/2008/12/25/load-all-fixtures-when-not-in-test/
include AuthenticatedTestHelper # restful authentification
include RspecResponseEnhancer # https://pragmatig.wordpress.com/2008/04/20/rspec-responseshould-information-enhancers/

Common steps
There is a nice collection of steps already available in steps/webrat_steps, but some basics where missing….

#features/step_definitions/common_steps.rb
When /^I click "(.*)"$/ do |link|
  click_link(link)
end

When /^I am on "(.*)"$/ do |path|
  header('Accept-Language','EN-en')
  visit path
end

Then /^I should be on "(.*)"$/ do |path|
  response.request.request_uri.should == path
end

Then /^I should see a flash about "(.*)"/ do |message|
  doc.search('div.flash_notice').inner_html.include?(message).should be_true
end

Then /^I should be logged in$/ do
  should be_logged_in
end

def doc
  Hpricot(response.body)
end

Output

 rake features
Feature: Signup  # features/signup.feature
  Scenario: A new user comes to the page and wants to register.  # features/signup.feature:2
    Given I am on "/"                                            # features/step_definitions/common_steps.rb:6
    When I click register                                        # features/step_definitions/common_steps.rb:1
    And I fill in "user[name]" with "Michael G"            # features/step_definitions/webrat_steps.rb:12
    And I fill in "Email" with "test@test.de"                    # features/step_definitions/webrat_steps.rb:12
    And I fill in "Password" with "test"                         # features/step_definitions/webrat_steps.rb:12
    And I fill in "Password confirmation" with "test"            # features/step_definitions/webrat_steps.rb:12
    And I press "Register for the free basic account"            # features/step_definitions/webrat_steps.rb:4
    Then I should be on "/"                                      # features/step_definitions/common_steps.rb:11
    And I should be logged in                                    # features/step_definitions/common_steps.rb:19
    And I should see a flash about "activation"                  # features/step_definitions/common_steps.rb:15

10 steps passed

Feels great to write stories again, sadly takes more time then unit tests, but the readability is superb! IMO a very nice way of doing integration tests…

Save All Empty Strings as NIL

With the  clear_empty_attributes plugin, all empty string worries are gone!

  • Complicate queries for empty fields (WHERE field IS NULL OR field = '')
  • Use of unless field.blank? (opposed to only if field)
  • Late-detected bugs because most of the time columns were filled or '' and suddenly they are nil
  • Some validations do not support :allow_blank=>true
  • Datebases can handle NULL better & faster than '' (especially when using LIKE)

Install

script/plugin install git://github.com/grosser/clear_empty_attributes.git

Now all empty strings will be saves as NULL.

Migrate

To take care of all other/old models we have to run a migration.
Remove any blank strings/texts from your Models:

rake clear_empty_attributes:clear_all_blank_strings MODELS=User,Movie,...

No More Whitespace Worries — Use HAML for Emails!

Tired of all the erb whitespace and those <%-end-%> madness ?

Switch to HAML for emails!!

How to?

  • remove any leading whitespace with capture and gsub
  • use == for easy string replacement
  • use == for newlines

Example

==Hello #{@user},
Your order has been completed on #{Time.now}.
You may now access the bought items:
==
- content = capture do
  - for item in @order.items
    - if item.shipping?
      We will send it to you soon.
    - else
      please download it here:
      ==#{item.orderable} -- #{polymorphic_url(item.orderable)}
    ==

=content.gsub(/^(  )*/,'')
==
=mail_signature