A Micropost model - The basic model: Generate Micropost model using
'rails generate model Micropost content:string user_id:integer'
The basic model: Add multiple key index on user_id and created_at columns
The basic model: The initial Micropost spec

Run the commands before run 'rspec spec'
$ bundle exec rake db:migrate
$ bundle exec rake test:prepare
The first validation: A failing test for the validity of a new micropost
If user_id is nil, it should be invalid
The first validation: A validation for the micropost’s user_id, and get the test pass
User/Micropost associations: Add failing tests for the User <-> Micropost associations

Using the 'belongs_to/has_many' association, Rails constructs the methods shown in below

Method                          Purpose
micropost.user                  Return the User object associated with the micropost.
user.microposts                 Return an array of the user’s microposts.
user.microposts.create(arg)     Create a micropost (user_id = user.id).
user.microposts.create!(arg)    Create a micropost (exception on failure).
user.microposts.build(arg)      Return a new Micropost object (user_id = user.id).

Pay attention to that instead of:
  Micropost.create
  Micropost.create!
  Micropost.new
We have:
  user.microposts.create
  user.microposts.create!
  user.microposts.build

This enable us to write test code like:
  let(:user) { FactoryGirl.create(:user) }
  before { @micropost = user.microposts.build(content: "Lorem ipsum") }
instead of:
  before { @micropost = Micropost.new(content: "Lorem ipsum", user_id: user.id) }

To test method 'micropost.user' we use 'its':
  subject { @micropost }
  its(:user) { should eq user }
User/Micropost associations: Use 'belongs_to' & 'has_many' to implement model associations

Pay attention to the plurality:
has_many :microposts // using plural
belongs_to :user  // using singular
Micropost refinements: Construct some microposts in the User model test using FactoryGirl

Technique:
We tell Factory Girl about the micropost’s associated user just by including a user in the definition of the factory
factory :micropost do
  content "Lorem ipsum"
  user
end

this allows us to define factory microposts as follows:

FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago)
Micropost refinements: A failing test for the order of a user's microposts

Technical:
We use 'let!' instead of 'let' because 'let' is lazy, variables spring into existence when referenced, while 'let!' create the variables immediately.
Micropost refinements: Ordering the microposts with 'default_scope'

Technicals:
1. A Rails facility called 'default_scope' with an 'order' argument
2. Use of Ruby Lambda expression
As of Rails 4.0, all scopes take an anonymous function that returns the criteria desired for the scope, mainly so that the scope need not be evaluated immediately, but rather can be loaded later on an as-needed basis (so-called lazy evaluation)
To understand the difference: In an early revision of the Rails Tutorial book 2nd edition, the code is:
default_scope order: 'microposts.created_at DESC'
instead of:
default_scope -> { order('created_at DESC') }

Lambda expression (Ruby syntax)
In Ruby, lambda is used to denote anonymous functions or closures
It is an operator which take a block and return an object of class Proc (procedure)
Ruby has alternative ways of creating Proc objects. Rather than write this:
  lambda { |params| ... }
you can also write the following:
  -> params { ... }
So '-> { order('created_at DESC') }' equals to 'lambda { order('created_at DESC') }'

Proc object can be called like this:
p1 = lambda {|n| 23 * n}
p1.call(3) # => 69
Micropost refinements: A failing test that when user is deleted, his microposts are deleted as well

Techniques:
1. microposts = @user.microposts.to_a
Here the call to to_a effectively makes a copy of the microposts. Without to_a, destroying the user would destroy the posts in the microposts variable, and as a result,
  microposts.each do |micropost|
    # Make sure the micropost doesn't appear in the database.
  end
wouldn't test anything because microposts would be empty.

2. Used Micropost.where instead of Micropost.find, because 'find' raises an exception if the record is not found, while 'where' returns an empty object.
Alternatively, you can use 'find_by_id' method which returns nil if record is not found
Or if you use 'find', you should write:
  lambda do // lambda again
    Micropost.find(micropost.id)
  end.should raise_error(ActiveRecord::RecordNotFound)
Or:
  expect do
    Micropost.find(micropost)
  end.to raise_error(ActiveRecord::RecordNotFound)
Micropost refinements: Add 'dependent: :destroy' option to implement cascade delete
Content validations: Add failing tests that micropost content should not be empty or longer than 140 characters
Content validations: Add a validation to Micropost's content to get the test green
Showing microposts:  A failing test for showing microposts on the user show page

Note we won't show microposts on a separate micropost index page
Showing microposts: Adding microposts to the user show page

Techniques:
1. We use '<%= will_paginate @microposts %>' comparing to '<%= will_paginate %>' in the user index page
This is because the user index page is in the context of the UsersController, 'will_paginate' assumes the existence of an instance variable called @users.
In present case, since we are still in the Users controller but want to paginate microposts instead, we pass an explicit @microposts variable to will_paginate. Of course, this means that we will have to define such a variable in the user show action.
2. The use of ordered list tag <ol>
Showing microposts: A partial for showing a single micropost

Techniques:
Use of 'time_ago_in_words' helper method for a text like 'Posted 3 minutes ago'

Note the tests are still failing. The error message is
     Failure/Error: before { visit user_path(user) }
     ActionView::Template::Error:
       'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path.
Because we have not defined instance variable @microposts in the UsersController, thus it doesn't know where to find the partial when it sees '<%= render @microposts %>'
Showing microposts: Adding an @microposts instance variable to the user show action

Now all tests are green
Sample microposts:  Adding microposts to the sample data

Remember to run commands:
$ bundle exec rake db:reset
$ bundle exec rake db:populate
$ bundle exec rake test:prepare

Techniques:
1. We create sample microposts for only the first 6 users in database, by using
User.all(limit: 6)
2. We use helper method Faker::Lorem.sentence to generate mockup text
Sample microposts: The CSS for styling microposts