Capturing an Order

Learn to make a user form to capture the order.

An order is a set of line items, along with details of the purchase transaction. Our cart already contains line_items, so all we need to do is add an order_id column to the line_items table and create an orders table based on the initial guess at the application data diagram.

First, we create the order model and update the line_items table:

depot> bin/rails generate scaffold Order name address:text email \
         pay_type:integer

depot> bin/rails generate migration add_order_to_line_item order:references

A live terminal

You can try the above commands in the terminal provided below:

Terminal 1
Terminal
Loading...

Notice that we didn’t specify any data type for two of the four columns. This is because the data type defaults to string. This is yet another small way in which Rails makes things easier for us in the most common case without making things any more cumbersome when we need to specify a data type.

Also note that we defined pay_type as an integer. While this is an efficient way to store data that can only store discrete values, storing data in this way requires us to keep track of which values are used for which payment type. Rails can do this for us through the use of enum declarations placed in the model class.

Now we will add this code to app/models/order.rb:

Press + to interact
class Order < ApplicationRecord
enum pay_type: {
"Check" => 0,
"Credit card" => 1,
"Purchase order" => 2
}
end

Finally, we need to modify the second migration to indicate that cart_id can be null in records. This is done by modifying the existing add_reference in line 3 to say null: true, and adding a new change_column in line 4 to enable nulls in the cart_id column.

Press + to interact
class AddOrderToLineItem < ActiveRecord::Migration[6.0]
def change
add_reference :line_items, :order, null: true, foreign_key: true
change_column :line_items, :cart_id, :integer, null: true
end
end
...