2. 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
3. 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
4. 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 ActiveRecordobjects Cryptographically signed but unencrypted Don’t store critical information solely in the session
5. Associate the cart with a session app/controllers/application_controller.rb private defcurrent_cart Cart.find(session[:cart_id]) rescue ActiveRecord::RecordNotFound cart = Cart.create session[:cart_id] = cart.id cart end
6. 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
7. Storing items in the cart rails generate scaffold line_itemproduct_id:integercart_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
8. 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’
9. Add Relationship Specifiers class Cart < ActiveRecord::Base has_many :line_items, :dependent => :destroy end class LineItem < ActiveRecord::Base belongs_to :product belongs_to :cart end class Product < ActiveRecord::Base has_many :line_items end
10. 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
11. What if we destroy a product? Make sure it isn’t contained in a cart
12. 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
13. 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) %>
14. 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
16. Update the functional test test/functional/line_items_controller_test.rb assigns() accesses instance variables in the controller being tested
17. Try it out http://localhost:3000/ Cart scaffolding didn’t show any attributes of what was just added
18. 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>
19. Try it out (again) http://localhost:3000/ Cart now shows what is contained Need to show each item only once (next chapter)
20. 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
Hinweis der Redaktion
- current_cart available to all controllers‘create’ an ActiveRecord method that creates & stores in the databaseas an aside, ‘private’ will look wrong to those from a Java or C# background
Other relationships are available - Many to Many - Relationships through a 3rd model
Can do things like li = LineItem.find(…) puts “This is for #{li.product.title}”Cart can reference its collection cart.line_items.count
Use an ActiveRecord callback to perform validation
- Unformatted data in validation callback
Links use HTTP GET, Buttons use HTTP POSTbutton_to uses <form> and <div> elements which drop down to another line unless made inline with CSS
ActiveRecord ‘build’ allows you to add an object to the collection with references set
- Updatetest to reflect changes in the controller- In the “real world”, we would update the test first- rake test:functionals