Home arrow Ruby-on-Rails arrow Page 4 - Checkout and Order Processing for an Ecommerce Website

Checkout and Order Processing for an Ecommerce Website

It's vital for an ecommerce website to get the checkout and ordering process correct. This five-part article series shows you how to use Ruby-on-Rails to manage it with very little difficulty. It's excerpted from chapter nine of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).

Author Info:
By: Apress Publishing
Rating: 5 stars5 stars5 stars5 stars5 stars / 4
July 08, 2010
  1. · Checkout and Order Processing for an Ecommerce Website
  2. · Implementing the Check Out User Story
  3. · Specifying the Associations
  4. · Adding Validations to the Model

print this article

Checkout and Order Processing for an Ecommerce Website - Adding Validations to the Model
(Page 4 of 4 )

We need to validate the billing information, but thereís one problem. We donít want to store that information in the database, so there are no fields in our model that we can validate. We can fix this by adding the code we have highlighted here to app/models/order.rb:  

class Order < ActiveRecord::Base
attr_protected :id, :customer_ip, :status, :error_message,➥
:updated_at, :created_at
attr_accessor :card_type, :card_number,➥
:card_expiration_month, :card_expiration_year, :card_verification_value

  has_many :order_items
has_many :books, :through => :order_items

Usingattr_accessorhas the same result as adding a getter and a setter for each of the attributes. However, it can all be done with one line, instead of something like this:

def card_type=(type)
@card_type = type

def card_type

Collecting correct information on the checkout page is important. If the customer misspells her e-mail address or forgets to enter information in one of the required fields, George might not be able to complete the order. To help prevent this, add the following validations to theOrder model (app/models/order.rb):

  validates_size_of :order_items, :minimum => 1
validates_length_of :ship_to_first_name, :in => 2..255
validates_length_of :ship_to_last_name, :in => 2..255
validates_length_of :ship_to_address, :in => 2..255
validates_length_of :ship_to_city, :in => 2..255
validates_length_of :ship_to_postal_code, :in => 2..255
validates_length_of :ship_to_country, :in => 2..255

  validates_length_of :phone_number, :in => 7..20
validates_length_of :customer_ip, :in => 7..15
validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
validates_inclusion_of :status, :in => %w(open processed closed failed)
  validates_inclusion_of :card_type, :in => ['Visa', 'MasterCard', 'Discover'],➥
:on => :create
  validates_length_of :card_number, :in => 13..19, :on => :create
:in => %w(1 2 3 4 5 6 7 8 9 10 11 12), :on => :create
:in => %w(2006 2007 2008 2009 2010), :on => :create
:card_verification_value, :in => 3..4, :on => :create

We validate all fields, including credit card information. The credit card fields are validated only oncreate, as they donít exist in the database.

We should also take care that the amount and price are correct, so add thevalidatecallback method shown here toorder_items.rb:

class OrderItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :book

  def validate
    errors.add(:amount, "should be one or more")➥
unless amount.nil? || amount >0
    errors.add(:price, "should be a positive number")➥
unless price.nil? || price > 0.0

This method validates that the customer is ordering at least one book and that the price is a positive number. Letís add the following test totest/unit/order_test.rb, which verifies that all fields are validated:

  def test_that_validation_works
    order = Order.new
    assert_equal false, order.save
    # An order should have at least one order item
    assert order.errors.on(:order_items)
    assert_equal 15, order.errors.size
    # Contact Information
    assert order.errors.on(:email)
    assert order.errors.on(:phone_number)
    # Shipping Address
    assert order.errors.on(:ship_to_first_name)
    assert order.errors.on(:ship_to_last_name)
    assert order.errors.on(:ship_to_address)
    assert order.errors.on(:ship_to_city)
    assert order.errors.on(:ship_to_postal_code)
    assert order.errors.on(:ship_to_country)

    # Billing Information
    assert order.errors.on(:card_type)
    assert order.errors.on(:card_number)
    assert order.errors.on(:card_expiration_month)
    assert order.errors.on(:card_expiration_year)
    assert order.errors.on(:card_verification_value)

    assert order.errors.on(:customer_ip)

Run the unit test one last time:

$ ruby test/unit/order_test.rb

You should see the tests pass.

Please check back tomorrow for the continuation of this article.

DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus

- Ruby-on-Rails Faces Second Security Flaw in ...
- Ruby 2.0 Prepped for February 2013 Release
- Why LinkedIn Switched from Ruby on Rails
- Adding Style with Action Pack
- Handling HTML in Templates with Action Pack
- Filters, Controllers and Helpers in Action P...
- Action Pack and Controller Filters
- Action Pack Categories and Events
- Logging Out, Events and Templates with Actio...
- Action Pack Sessions and Architecture
- More on Action Pack Partial Templates
- Action Pack Partial Templates
- Displaying Error Messages with the Action Pa...
- Action Pack Request Parameters
- Creating an Action Pack Registration Form

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 

Developer Shed Affiliates


© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials