Code Academy Week 8 Notes

2012-02-28_08.18.14
undefined method model name for NilClass:Class
Means there is a problem with the model
So instantiate it in the controller from the session

How to override application.html.erb for a controller or action

For orders controller, app/views/layouts/order.html.erb
To specify layout:
in controller:

or in def new:

we need to encrypt the credit card number. Look in config/application.rb
We will look at
config.filter_parameters +=[:password]
This will filter password out of the log
So we can add to the array
config.filter_parameters +=[:password, :card_number]

asset pipeline: We will talk about it throughout the week. Look in the assets folder. Images, javascript and stylesheets.
It takes all the javascript and puts it in one file, so the browser only has to make one request
Same for css
For css, you should go to application.css and specify files and/or directories

require_tree will do everything aplhabetically. You can put them in your own order.

In development mode, there is no asset pipeline. You use it in production.

In config/environments/development.rb

if you set that to false, you won’t see the GET requests in the logs for EVERY js and css file

Jeff can get to other order pages as well as his own
We have authentication. What about authorization?
In orders controller:

WHat if that ID is not in the order table?

You could do this:

But then it looks like redirect is the default.
Or

Moving this to a one-liner could make it a but confusing
You could also do

or

Stay at same level of abstraction throughout the html.erb files
if you have render tags with low-level html, that could look bad

Class method that makes an ActiveRecord call
Use the scope facility
Instead of:

 

scope creates a class-level method, and returns rows
You cannot just return one row

Maybe we want to pass a param from the view to the class-level method or scope

Easy for method.
For a scope:

Orders Controller:
We have a before_filter
We have model callbacks in cart_item.rb
Those are sort of like lambdas as well.
We do not call it, Rails calls it for us at some point.

Let’s do a scope on price for products:

Then in the view you could chain the scopes

Lambda with a default value for min:

Getting the data you want:

You can also use % for wildcards

In Products Controller:

or

So why not do this? Jeff will explain
You could get SQL injection
So do this:

Use the question mark placeholder

ActiveRecord will create the SQL for you
Fuzzy search:

Then in the controller you could chain the methods

It is not until you get to the @products.each (or a .all) in the view that you run the query

Should you use the products controller for searching, or make a search controller?
the form_tag goes to ‘/products’ with a get, which will go to the index action
—-
New app:
User Story Analysis
1. Identify resources
2. Create Models
3. Implement business rules
4. Create User Interface

Some people go in the opposite order

Air Academy User story
1. As a visitor, list the flights

In Rails 3.2, when you generate model, if you do not specify the types it will assume that it is a string
rails g model Airport code:string city:string
ericm@finance:~/ruby/ca_files/air$ more db/migrate/20120228174012_create_airports.rb

emacsnw db/migrate/20120228174012_create_airports.rb

For flights, we need two airports, not just one departure_airport_id, arrival_airport_id

If you say belongs_to :blah, the table needs a column blah_id
If that is the only belongs_to, Rails will assume there is a Blah model

2012-03-01_08.38.49
Pagination:
Kaminari, Will_paginate, roll your own

User story: As a user, I want to make a reservation
As opposed to doing something “as a visitor”
Different permissions, etc
So for “As a user” that user story needs an account
User story analysis
1. Identify resources
2. Create models
3. Implement business rules
4. Create user interface

reservation model has user, a flight, chosen departure date, credit card number
Associations:
user can have many reservations
flight has many reservations
reservation belongs to flight and belongs to user

departs_on for dates, departs_at for times

How to decide to model or scaffold? How much of scaffold will you use?

add_index on the reservation table
add_index is outside the create_table block

Good to have indexes for foreign keys
Then run

rake db:migrate:reset will drop database and recreate tables
rake db:seed
You could do

——————
Now JC from DevMynd is talking
database: structured set of data on a computer, accessible in various ways
five categories: relational, graph, key-value, document, column family databases
Relational database: built around relational theory (first-order predicate calculus), schema defined in tables of columns and rows, data is related through matching keys
Graph: based on graph theory. These DBs use nodes, properties and edges to describe a “web” of data. They can be powerful for complex ancestral queries (Amazon: People who bought X bought Y)
Key-value: primary way of retrieving objects is by a single key. What can be stored as a value varies.
Redis is used for queing systems
Document database: storing document-oriented, semi-structured data. Normally within a loose schema and the ability to store/retrieve nested structures
Column-family database: inverse of relational model. Big table.
Choosing data store can be pretty complex.
Considerations: indexing, querying, scaling, modeling, mapping, analyzing, recovering
Indexes: a parallel description of your data optimized for fast lookup
If you will ever do an order_by or a conditional query
Finding by department and last name is different than index that finds by last name and first name
Querying: getting info from db. Do we use a template object, a query language, or a string key?
Mongo can use query syntax, or you can pass in a template doc
scaling: scale up (faster, bigger hardware) or out (distributing data, indices and queries across more machines, aggregating the results)
mongo can shard well, so can redis
modeling: is your schema fixed or flexible? a few large things, lots of small things
Mapping (ORM) – ActiveRecord for RDBMS, Mongoid for MongoDB, Redis ruby driver
how will you interact with db?
analysis: what does the database provide?
recovery: relational: replication, push log to another system
Mongo: backup and restore tools
Heroku, other cloud backups are not that great

optimization: this is usually the first bottleneck
universal: careful indexing, duplication
relational: de-normalization, pivoting, materlialized views
normalized: each concept in a different table, less repetition
pivot: making rows into columns, and vice versa
materialized views:
non-relational: nest relationships, parallel queries
downside of indexing: it can take a LOT of space, plus index might be held in memory instead of disk
Put query logic in your model, not your controller
So if you change the datastore, you can just change it in the model class
relational tables good for complex joins
Think carefully about uniqueness and nullability early on

——————
Back to Jeff
For flight page, give some info about flight
the user is part of the session
reservation for
So in reservation controller, in new method: @user = User.find(session[:user_id])
You could do it from show page for a flight
@user = User.find()
Get stuff from flight show page
Reuse the flight_details partial

But we could get a Nil
So in the reservations controller
We will do something in def new
We could have a link from flight show page
@flight.id) %>
So in new,

So we want to put that link in an if on the flight show page
Put a filter on the reservations new controller

@flight.id) %>

In reservation form:

in reservation controller.new:

validation on reservations:

create method in reservationcontroller:

Sending email in Rails – it could depend on your host

In our reservation controller, we will use this in respond_to block

in ReservationMailer

So in app/views/reservation_mailer/confirmation.text.erb
Hello, ,
Thanks for sending us $300.

Flight details
———————
Flight number: