SpicyCode

The ramblings of Chad Humphries

Posts Tagged ‘rails

Revisiting the documentation project

I was up late last night and I ended up at the caboo.se rdoc project again. In case you haven’t heard caboo.se is running a documentation drive for rails.

They have a site up at rdoc.caboo.se that allows you to view the rails docs and submit documentation changes inline.

Take 20 minutes one day and see if there is something you can help improve the documentation for. It’s one easy way we can all give back to the community.

Advertisements

Written by spicycode

February 17, 2008 at 6:01 pm

Posted in programming

Tagged with ,

Bitten by the hard breaks again

Another turn around the textile wheel of fortune in a rails application today yielded a lesson learned long ago but forgotten.

The textilize helper included with rails enables the hard_breaks mode by default. Hard Breaks converts 1 new line to a br and 2 newlines to a p tag. When you disable hard breaks mode you only get p tags.

Here’s how the source for that method looks:

def textilize(text)
  if text.blank?
    ""
  else
    textilized = RedCloth.new(text, [ :hard_breaks ])
    textilized.hard_breaks = true if textilized.respond_to?("hard_breaks=")
    textilized.to_html
  end
end

Here’s a simple override of it you can put in your application_helper.rb if you want the no hard breaks behaviour.

def textilize(text)
  if text.blank?
    ""
  else
    RedCloth.new(text).to_html
  end
end

Nothing new, just posting it here as a reminder to myself and a hopefully helpful tip to anyone not yet familiar with this difference.

Written by spicycode

May 13, 2007 at 6:12 pm

Posted in programming

Tagged with , ,

Rspec Expectation Matchers – Part II

The new release of my RSpec extensions gem (along with a newly minted plugin version) will be out within a day or two. Barring any major show-stoppers I just need to finish adding :message => specification support so you can indicate what error message you expect to receive if it is invalid (if you choose to). Once that is in I’ll let the release notifications fly.

The goal of these expectation matchers is to allow you to test validations, and associations easily. Whether or not you wish to test these items I will leave up to you, but if you choose to this will definitely help keep things simple and quick.

Poor mans code outline

validate_presence_of(attr, options = { })
#    ex:  model.should validate_presence_of(:name)
#           model.should validate_presence_of(:name, :valid_value => 'Bob', :invalid_value => nil)
validate_confirmation_of(attr, options = { })

validate_uniqueness_of(attr, options = { })

validate_acceptance_of(attr, options = { })

validate_associated(associated_model, options = { })

validate_exclusion_of(attr, options = { })

validate_format_of(attr, options = { })

validate_inclusion_of(attr, options = { })

validate_length_of(attr, options = { })
alias_method :validate_size_of, :validate_length_of
#    ex:  model.should validate_length_of(:name, :within => 3..30)
#          model.should validate_length_of(:name, :maximum => 100)

validate_numericality_of(attr, options = { })

have_association(type, name, options = {})

belong_to(name, options = {})
#  ex: model.should belong_to(:parent)
#             (or more detail) model.should belong_to(:parent, :class_name => 'People')
have_one(name, options = {})

have_many(name, options = {})

have_and_belong_to_many(name, options = {})

Example usage:

context "A User" do

  setup do
    @user = User.new(valid_user_attributes)
  end

  specify do
    @user.should validate_presence_of(:first_name)
  end

  specify do
    @user.should validate_length_of(:first_name, :in => 1..50)
  end

  specify do
    @user.should validate_presence_of(:last_name)
  end

  specify do
    @user.should validate_length_of(:last_name, :in => 1..50)
  end

  specify do
    @user.should validate_presence_of(:username)
  end

  specify do
    @user.should validate_length_of(:username, :in => 3..40)
  end

  specify do
    @user.should validate_presence_of(:email)
  end

  specify do
    @user.should validate_length_of(:email, :in => 3..100)
  end

  specify do
    @user.should validate_presence_of(:password)
  end

  specify do
    @user.should validate_confirmation_of(:password)
  end

  specify do
    @user.should validate_presence_of(:account_id)
  end

  specify do 
    @user.should belong_to(:account)
  end

  specify do 
    @user.should have_many(:project_assignments)
  end  

  specify do 
    @user.should have_many(:projects, :source => :project, :through => :project_assignments, :order=>"projects.name")
  end

end

Example output:

A User
- should validate presence of first_name
- should validate length of first_name
- should validate presence of last_name
- should validate length of last_name
- should validate presence of username
- should validate length of username
- should validate presence of email
- should validate length of email
- should validate presence of password
- should validate confirmation of password
- should validate presence of account_id
- should have a belongs_to association called :account
- should have a has_many association called :project_assignments
- should have a has_many association called :projects

Written by spicycode

April 1, 2007 at 5:55 pm

Posted in programming

Tagged with , ,

oooh shiny! rspec extensions for activerecord validations

I’m currently in waiting for rubyforge approval limbo for my new rspec extensions project but I figured I would post about it anyway.

Step 1 – Identify something that annoys you

  • In this case repeatedly writing validation specifications

Step 2 – Fix a problem

  • Write gem to package up solution…in this case spicycode_rspec_extensions

Step 3 – Profit?

  • Ok, so no step three, but it sounded good at the time.

So what does it do?

I started out with the simplest cases I was repeating basing it off of David’s excellent post about custom expectation matchers, more will come later. See the awe-inspiring and mind boggling (well, at least mind boggling) examples below. This does require rspec 0.8.2 or above.


context 'A User (when validating)' do
  ...
  setup do
    @user = User.new(valid_user_attributes)
  end

  specify do
    @user.should require_presence_of :first_name
  end

  specify do
    @user.should require_confirmation_of :password
  end
   ...
end

After running you will get output like the following thanks to RSpec’s automatic naming abilities


A User (when validating)
- should validate presence of first_name
- should validate confirmation of password

Finally, if something were to not match it will print out what was wrong with the object (the objects current errors).

Recap?

Well hopefully some of what I said made sense to someone 🙂 I’ll be pushing the gem up to ye olde ‘forge as soon as the project approval comes through.

Written by spicycode

March 19, 2007 at 5:56 pm

Posted in programming

Tagged with , ,

Custom expectations in rspec (pre 0.8.0)

Nothing special, just a simple helper I threw together a while back. It is used in model tests to verify that a column is required. A few usages follow. Note: this will be completely replaced in rspec 0.8.0 by custom expectation matchers. But I’ve had this one around for a while in one form or another, so I figured I’d post it up in case it helps anyone.

The code

 1   def should_require_attribute(model, attrib_name, error_messages=[], invalidvalue=nil)
 2     # Collect the valid value
 3     valid_value = model.send(attrib_name)
 4     error_messages = error_messages.to_a.sort
 5     
 6     # Set it to nil
 7     model.send("#{attrib_name.to_s}=", invalid_value)
 8 
 9     model.should_not_be_valid
10     model.should_have(error_messages.size).errors
11     model.errors.on(attrib_name).to_a.sort.should == error_messages
12     
13     # Put things back where you found them
14     model.send("#{attrib_name.to_s}=", valid_value)
15     model.should_be_valid
16   end

Usage

 1 # Simple case
 2 specify "should be invalid without state" do
 3    should_require_attribute(your_model, :state, "is required")   
 4 end
 5 
 6 # More than one error expected
 7 specify "should require a valid email address" do
 8    should_require_attribute(your_model, :email_address, ["is required", "should be a valid format"])   
 9 end
10 
11 # Invalid value other than nil
12 specify "should require a non .gov email address" do
13    should_require_attribute(your_model, :email_address, "can't contain .gov domains", "bigbrother@government.gov")   
14 end

Written by spicycode

February 23, 2007 at 6:00 pm

Posted in programming

Tagged with , ,

Sessions keys and initializers oh my…

Rails revision 6198 added support for configuration of your session secret and key (following up to the cookie based session support recently added).

1   # Inside Rails::Initializer....
2   # Your secret key for verifying cookie session data integrity.
3   # If you change this key, all old sessions will become invalid!
4   config.action_controller.session = {
5     :session_key => '_<%= app_name %>_session',
6     :secret      => '<%= CGI::Session.generate_unique_id(app_name) %>'
7   }

Additionally support was added for a new folder config/initializers which is automatically loaded as part of the initialization process in 6212 and 6213.

The two example files given are config/initializers/inflections.rb and config/initializers/mime_types.rb.

I’m guess config/initializers was intended to simplify some of the config after_initialize code some apps have creeping into them requiring a variety of files.

Written by spicycode

February 23, 2007 at 5:01 pm

Posted in programming

Tagged with ,

This isn’t where I parked my car…

Late last night I decided to perform my international duty and post a code snippet I have in my irbrc to Tim Lucas’s blog. Given that it seemed useful to Tim and others I thought I’d repost it here.

1 script_console_running = (ENV.include?('RAILS_ENV') and IRB.conf[:LOAD_MODULES].include?('console_with_helpers'))
2 
3 rails_running = (ENV.include?('RAILS_ENV') and !IRB.conf[:LOAD_MODULES].include?('console_with_helpers'))
4 
5 irb_standalone_running = (!script_console_running and !rails_running)

The code you just saw should be place anywhere near the top of your irbrc. You can then use any of the three variables available to run context specific IRB code.

Do you know of any other good bits of code magic for your irbrc file?

Written by spicycode

February 6, 2007 at 6:03 pm

Posted in programming

Tagged with ,