cart creation-101217222728-phpapp01
DESCRIPTION
Presentation give by Alan Hecht.TRANSCRIPT
Cart Creation
What we’ll cover
• Using Sessions• Public, Private, and Protected Methods in
Ruby• Relationships between models• Active Record Callbacks & Validation• Adding a button to a page• More Functional Testing
Generate a shopping cart
• rails generate scaffold cart– No foreign keys present– Only one of the tables has a foreign key
• Need to recover the cart with every request
Rails Sessions
• By default, session info stored in a browser session cookie (4k limit)– Database or memcached also available
• Don’t store data that can easily be outdated– Serialized ActiveRecord objects
• Cryptographically signed but unencrypted• Don’t store critical information solely in the
session
Associate the cart with a session
• app/controllers/application_controller.rb
private def current_cart
Cart.find(session[:cart_id]) rescue ActiveRecord::RecordNotFound cart = Cart.create session[:cart_id] = cart.id cart
end
Public, Private, & Protected Methods
• Different from Java & C#• Public methods can be invoked by anyone • Private methods accessible by an object from a
derived class• Protected methods accessible by other objects
& objects from derived classes• Inheritance doesn’t determine method visibility– Private & protected methods visible from
subclasses
Storing items in the cart
• rails generate scaffold line_item product_id:integer cart_id:integer– By convention, singular of table name appended
with “_id”– Need to establish relationship in both the
database and the model– Model declarations add ability to build and
navigate the relationship
ActiveRecord relationships
• One to One– has_one :contained– belongs_to :container
• One to Many– has_many :contained– belongs_to :container
• Table with foreign keys has the ‘belongs_to’
Add Relationship Specifiers
class Cart < ActiveRecord::Base has_many :line_items, :dependent => :destroyend
class LineItem < ActiveRecord::Base belongs_to :product belongs_to :cartend
class Product < ActiveRecord::Base has_many :line_itemsend
What if we destroy a cart?
• Line_items dependent on cart– :dependent => :destroy indicates that line_items
are destroyed along with the cart– destroy involves ActiveRecord validation logic,
delete only removes from the database
What if we destroy a product?
• Make sure it isn’t contained in a cart
ActiveRecord Callbacks & Validations
• Callbacks invoked before & after operations– For example save, delete, create, validate– Can view unformatted data in ‘before’ callbacks• Dates & Currency
• Returning the actual value ‘false’ stops the operation
• Add a handler or define as a method
Add a button• Won’t be creating a new controller or a new action
– Creating an item in the cart, so use line_item controller– Looking at generated code in line_item_controller.rb, we’ll use
the ‘Create’ action– ‘Create’ action called using HTTP Post
• button_to ‘button label’, ‘URL Path’, ‘HTML options’– Add ‘_path’ to controller to get URL path (i.e. line_item_path)– Pass in hash values to URL path as parameters– id extracted from ActiveRecord objects passed in
• app/views/store/index.html.erb<%= button_to ‘Add to Cart’, line_items_path(:product_id => product) %>
Modify line_item create
• By default, create parameter is a serialized line_item object - params[:line_item]
• Create a line_item based on the product id and add it to the cart
Modify line_item create (cont.)
• app/controllers/line_items_controller.rb
Update the functional test
• test/functional/line_items_controller_test.rb
– assigns() accesses instance variables in the controller being tested
Try it out
• http://localhost:3000/
– Cart scaffolding didn’t show any attributes of what was just added
Modify the view
• app/views/cart/show.html.erb
<h2>Your Pragmatic Cart</h2><ul> <% for item in @cart.line_items %> <li><%= item.product.title %></li> <% end %></ul>
Try it out (again)
• http://localhost:3000/
– Cart now shows what is contained– Need to show each item only once (next chapter)
Homework
• Change the view so that clicking on a book’s image will also add the product to the cart
• Add a new session variable to record how many times the user accessed the store controller’s index action
• Add the counter to the template and display it on top of the catalog page
• Reset the counter to zero when adding to the cart
• Change template to display counter when > 5