Wednesday, June 17, 2015

Ruby on Rails 2015-06-16

1. Route the pages.
(1) If you want to be able to route to your new view, open config/routes.rb and add the line

get 'view_name/index'

(2) If you want to set the default page to a certain, open config/routes.rb file, add

root 'store#index', as: 'store'

So the index will be routed to the index of controller store. The as: 'store' tells Rails to create a store_path accessor method.

2. yield method in view/layouts/application.html.erb. This method will render the content of the view that user is currently browsing. For example, if the user is browsing http://localhost/store, then the content of views/store/index.html.erb will be rendered in the yield section. Similarly, if the user is browsing http://localhost/products, then the content of views/products/index.html.erb will be rendered.

3. Did "rake test" but encountered five errors:
(1) AbstractController::Helpers::MissingHelperError: Missing helper file helpers//users/alexsun/documents/rubys/workspace/depot/app/helpers/application_helper.rb_helper.rb

(2) ProductsControllerTest#test_should_show_product:
ActionView::MissingTemplate: Missing template products/show, application/show with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]} 

(3) - (5) similar to (2), all are "Missing template"

I didn't see these error when I was using Ruby 2.2.0. But after that I switched back to Ruby 2.0.0 and then these error appears. I fixed them by changing my workspace name "Depot" to "depot" and all errors are gone. It seems to me a Ruby bug which is in Ruby 2.0.0 but fixed in Ruby 2.2.0.

Monday, June 15, 2015

Ruby on Rails 2015-06-15

Object-Relational Mapping

ORM libraries map database tables to classes. If a database has a table called products, the program will have a class named Product. Rows in the table correspond to objects of the class -- a particular product is represented as an object of class Product.

ActiveRecord is the ORM layer supplied with Rails. It closely follows the standard ORM model: tables map to classes, rows to objects, and columns to object attributes. By relying on convention and starting with sensible defaults, ActiveRecord minimizes the amount of configuration that developers perform.

To understand the ActiveRecord, here is the example:
In models/product.rb, a class Product is define:
class Product < ActiveRecord::Base
end

In db/migrate/xxx_create_products.rb, a class CreateProducts is define:
class CreateProducts < ActiveRecord::Migration
    def change
        create_table:products do |t|
        end
    end
end

By this way, Product has been mapped to the prodcuts table in the database. And the cool thing is that the Product calss that wrap the database table provides a set of class-level methods that perform table-level operations. To understand this, here is the example:
(1) find the product with a particular ID
product = Product.find(1)
(2) collect the objects whos name is 'dave'
product = Product.where(name: 'dave')
You don't need to care about how to manipulate the SQL query to get the data. Rails class wraps them for you and all you need to do is code like OO programming.

Ruby on Rails 2015-05-23

1. Rails provides a simple way to do data validation. The model layer is the gatekeeper between the world of code and the database. If a model checks the data before writing to the database, then the database will be protected from bad data. The source code is in app/models/xxx.rb. An example of validation is:
    validates :title, :description, :image_url, presence: true

2. Rails provides a test framework. The framework is in test directory. You can test the entire framework by:
    $ rake test
Unit test cases can be created in test/models directory, and you can test a particular test case file, e.g.:
    $ rake test:models

3. We use assertion to tell the framework whether our code passes or fails.  The simplest assertion is the method assert(), which expects its argument to be true, e.g.:
    assert product.invalid?, "DEBUG COMMENTS"
    assert product.errors[:title].any?

4. Fixture is a specification of the initial contents of a model under test. Fixture data is specified in the test/fixture directory. The name of the fixture file is significant. The base name of the file must match the name of a database table. The default for the test is to load ll fixtures before running the test, but again you can control which fixtures to load by specifying the following line in the test/models/xxx_test.rb:
    class ProductTest < ActiveSupport::TestCase
      fixtures :products
      ...
    end
The name of the fixture file determines the table that is loaded, so using :products will cause the products.yml fixture file to be used.

5. There are three databases that has been created in the configuration that scaffolding provides.
(1) db/development.sqlite3 will be the development database.
(2) db/test.sqlite3 is a test database.
(3) db/production.sqlite3 is the production database.
rake test command automatically gets a freshly initialized table in the test.sqlite3 database loaded from the fixtures we provide. Also we can do it separately by running rake db:test:prepare.