How to Build a Basic E-Commerce Store
Or at least, how I did it with Rails
For the past two weeks, we’ve been working on the shopping app. Decided to redo it because I realized it’s a good way to learn, and also because it might help someone out there!
Repository at: https://github.com/kennethteh90/shopping-app-redo.git
Heroku at: https://shopping-app-redo.herokuapp.com/
Overall steps to consider
- Products and Categories
- User: what does the user have access to? And after logging in?
- Admin: what does the admin have access to?
- Shopping Cart (Redis, sessions)
- Payments/Orders
- Optional: Product photos
- Optional: Facebook Login
- Optional: Emails
Step One: Products and Categories
This should be pretty normal by this point! Very similar to the Twitter Clone last time.
Main Ideas
- Create product and category models, views and controllers
- At this point, we have to decide how the categories and products are related. For my app, I chose to have a many-to-many relationship between the two, because a piece of clothing might be a product for men, but it might also be on sale. For your app/store, it might make more sense to have a one-to-many relationship, e.g. if the categories are very clearly defined and separate.
Actual Code:
Migrations
Models
Routes
Controllers
Views
products/index
I chose to use a partial here, making use of the collection to show each product.
shared/product
products/show
categories/show
Gems
What it looks like:
And don’t worry if your app is showing a blank screen! I added a product and a category in rails console.
Step Two: User
Main ideas
- Use devise!
- Decide what the user has access to: should the user be able to access your app without logging in? (for most stores, the user should at least be able to see the products!)
- And after logging in? (checkout?)
I won’t belabor the point here, I’m sure you’re all familiar with Devise by now! If you need a refresher, head on over to my Twitter guide where I have all the instructions.
At this point, I haven’t done much with authentication yet. An anonymous user should be free to browse our site! We can move on to creating the Admin user.
I like this way of displaying flash messages:
Step Three: Admin user
Main Ideas
- Use devise to create an admin model
- Create namespaced route for admin
- Create controllers and views for admin
- Admin will be able to create/edit products and categories
Devise instructions
First generate the model and migration for the Admin role:
$ rails generate devise Admin
Configure your Admin model:
class Admin < ActiveRecord::Base
devise :database_authenticatable, :trackable, :timeoutable
end
From: https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-Role
Actual Code:
Model
You can run Admin.create in the rails console to add your admin account.
Routes
Controllers
controllers/admin/categories
controllers/admin/products
Note here the @category_array that I’m using to create the association between the product and categories. Will revisit this at the views.
Note here that you have to destroy all associations first before adding them again (this is not the only way nor is it at all the best way, it just happens to be the only way I know!)
Views
admin/categories/index
admin/categories/_admin_category
admin/categories/new (edit is the same)
admin/products/index
admin/products/_admin_product
admin/products/new (edit is the same)
As promised, a comment here. The line f.association allows you to collect input for an associated model (Category in this case) from the product form. No more nested attributes required!
Added a basic navbar to application.html.slim:
What it looks like:
Admin dashboard
Step Four: Shopping Cart (Redis, sessions)
Main Ideas
- Install Redis
- Add Carts controller and view, new routes
- Add partial that shows the current cart count
- Create ‘Add to cart’ and ‘Remove from cart’ buttons
Installing Redis
I followed this guide:
In terminal:
sudo apt-get update
sudo apt-get install redis-server
sudo apt-get update
sudo apt-get install php-redis
redis-server
For the actual shopping cart implementation, I followed this guide, but made some modifications:
Add gem: gem 'redis'
(already done earlier in this guide)
Initialize the Global Object
Create an initializer file named /config/initializers/redis.rb where we’ll set up our Redis connection. A global variable will be created to allow easy access in the rest of our app. Also, specify
hiredis
as the driver when instantiating the client object.
$redis = Redis.new
Actual Code:
Model
This is the tough bit where you add Redis calls to your code:
Routes (added the cart resource)
Note that this is resource, not resources. Also added the three custom routes to add and remove from the cart.
Controller
Views
products/show (added the ‘Add to Cart’ button)
carts/show
Navbar (added the cart and a couple of line about the user login)
What it looks like:
Step Five: Payments
Main Ideas
- I used Braintree to do my payments.
- I used dotenv to hide my environment variables (they used Figaro)
Followed this guide:
It’s very self-explanatory, the only gotcha is that the gon version in the guide is outdated, so please use gem ‘gon’, ‘~> 6.2.0’
Actual Code:
Migration
Models
/config/initializers/braintree.rb (create this file)
Routes (add transactions and orders)
Controllers
Views
admin/orders/index
admin/orders/_admin_order
transactions/new
carts/show (add checkout link)
Javascripts
application.js (add jquery and jquery_ujs)
transactions.coffee
Updated Navbar
What it looks like:
That’s all for now! Maybe I’ll have more time to work on this next week. For now, I need to focus on learning React!
For the rest of the steps (Optional: Product photos, Facebook Login, Emails), do let me know if this is something that will be helpful for you, if so, I’ll take some time to do it during the week.