Coursera上關於web開發的一門好課,以Ruby on Rails爲基礎講述web開發的方方面面,包括網絡架構、設計模式、版本控制等等,老師講述非常清晰,值得推薦。簡單做了些備忘筆記。
課程地址:https://www.coursera.org/course/webapplications
果殼MOOC學院介紹地址:http://mooc.guokr.com/course/967/Web-Application-Architectures/
Module 1: Introduction and Background
Web 1.0, 2.0, 3.0
- Web 1.0 – Creation of static web sites, the first web business models.
- Web 2.0 – Interactivity (Ajax), social networking, mash-ups, media sharing, online commerce, lightweight collaboration, wikis.
- Web 3.0 – The “intelligent web”, i.e., machine-facilitated understanding ofinformation. E.g., semantic web, NLP, machine learning/reasoning, recommender systems.
Client-Sever Model
Web Application Architecture Tiers
Module 2: Ruby on Rails
Model-View-Controller
搭建環境ruby on rails
環境
Mac使用Homebrew
快速安裝
mac雖然自帶ruby,但是版本較老,建議使用Homebrew
進行安裝。
$ brew install ruby
# 由於國內網絡原因,建議換成淘寶gem源,參考:http://ruby.taobao.org/
$ gem sources --remove https://rubygems.org/
$ gem sources -a https://ruby.taobao.org/
$ gem sources -l
*** CURRENT SOURCES ***
https://ruby.taobao.org
# 請確保只有 ruby.taobao.org
# 安裝rails,速度較慢,且中間有些過程無提示,請耐心等待
$ gem install rails
創建一個rails應用
$ rails new blog
$ cd blog
$ rails server
# 打開 http://localhost:3000
rails項目目錄詳解
博客應用初始化
rails new blog
# 創建文章和評論組件
rails generate scaffold post title:string body:text
rails generate scaffold comment post_id:integer body:text
# 生成數據庫表
rake db:migrate
# 顯示所有URL路徑
rake routes
Rails 哲學
- 多約定,少配置 Convention over Configuration: Rails 爲網頁程序的大多數需求都提供了最好的解決方法,而且默認使用這些約定,不用在長長的配置文件中設置每個細節。
- 不要自我重複 Don’t Repeat Yourself (DRY):DRY 是軟件開發中的一個原則,“系統中的每個功能都要具有單一、準確、可信的實現。”。不重複表述同一件事,寫出的代碼才能更易維護,更具擴展性,也更不容易出問題。
- 敏捷開發 Agile Development:每次都做出一個做小可用版本,然後不斷迭代更新。
版本控制
Git Workflow–Remote Repository
Module 3: Database Interactions
- 關係型數據庫
- join table(多對多關係用join table來連接)
- Schema and Entity-Relationship Models
- 可以使用mysqlworkbench來進行方便的建模
Rails Environments
- Development:開發環境。
rails server
默認使用其啓動。 - Test:測試環境。
- Production:應用環境。使用命令
rails server -e production
強制指定應用以生產環境啓動。
Active Record Design Pattern
通過將對象(object)和關係(ralation)進行映射(ORM- object-relational mapping),使得程序裏可以使用一個“虛擬對象數據庫”來實現CRUD(數據庫的增、查、改、刪)。
在rails中使用ActiveRecord
模塊來實現。
ActiveRecord
模塊解析
- 模塊定義
ActiveRecord::Base.establish_connection
:使用./conifg/database.yml
中的配置將rails應用連接到數據庫ActiveRecord::Migration
:用來增量更新數據庫模板,放進./db/schema.rb
文件ActiveRecord::Schema.define
:在./db/schema.rb
文件中,用來表達數據庫結構,與具體使用的數據庫類型無關。可以被載入任何ActiveRecord
支持的數據庫。
- 模塊使用
- 如果從
ActiveRecord::Base
繼承新建類Post
,則程序會假定存在數據表posts
,並從數據庫中將其各項數據賦值到該類中(通過ORM) - 可以用該類直接調用部分SQL語句,如:
Post.all
Post.first
Post.find_by(1)
Post.find_by_title("my first blog")
- 如果從
Ruby交互命令行
# 原生解釋器
$ irb
# 從rails應用根目錄執行,會自動載入rails環境,並有自動補全功能
$ rails console
Associations in Rails
使用方法示例:
# in blog/app/models/post.rb
class Post < ActiveRecord::Base
has_many :comments
end
# in blog/app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
end
ActiveRecord Validations
rails在生成model的時候進行數據驗證:
Module 4: The Ruby Programming Language
執行ruby腳本
# 列出所有gem包
$ gem list
# 直接命令行執行ruby語句
$ ruby -e 'puts"hello world!"'
hello world!
# 執行ruby文件
$ ruby hello.rb
ruby類
class MyClass # 創建類
@boo # 變量,無法訪問,需要設定指定讀寫的方法
def my_method # 方法
@foo = 2
end
def self.cls_method # 類方法
"MyClass type"
end
# attr_reader, attr_writer
attr_accessor :name, :age # 直接創造可以讀寫的變量
end
class MyClass2 < MyClass # 類繼承
attr_accessor :special
end
mc = MyClass.new # 創建對象
mc.my_method # 執行方法
# mc.boo # 報錯
MyClass.cls_method # 調用類方法
變量命名通用規則:
- name
– could be a local variable.
- @name
– an instance variable.
- @@name
– a class variable.
- $name
– a global variable.
Strings 和 正則表達式
# string內置變量
> "360 degrees=#{2*Math::PI} radians"
=> "360 degrees=6.283185307179586 radians"
# 反引號執行命令
> `date`
=> "Tue Oct 15 09:10:21 MDT 2013\n"
# 正則匹配,返回第一個匹配的index,無匹配返回nil
> "Homer" =~ /er/
=> 3
Symbols
ruby中使用symbol表示“名字”,創建方法是在字符串加上冒號,如:foo
或:"foo"
。其與string 的區別爲:
- symbol在整個ruby運行期間只有一個,相同的symbol在內存中只有一份;而string是隨用隨建,即使內容相同的string也會創建不同的兩個string對象
- string是可變的,而symbol不可變
- string多用於表示需要改變的文本,而symbol用於key
詳細區別可參見理解 Ruby Symbol。
> puts :name.object_id # => yields 20488
> puts :name.object_id # => yields 20488
> puts :"name".object_id # => yields 20488
> puts "name".object_id # => yields 2168472820
> puts "name".object_id # => yields 2168484060
Array, Hash, Iterators
# Array
> a = [33.3, "hi", 2]
> a[0] # => 33.3
> a[1..2] # => ["hi", 2]
> a << 5 # => [33.3, "hi", 2, 5]
> a[-1] # => 5
> a.include? 2 #=> true
# Hash
phone = {:home => 1, :mobile => 2, :work => 3}
> phone[:home] # => 1
> phone.key(1) # => :home
> phone.key?(:home) #=> true
> phone.value?(1) #=> true
# Iterators
> a = [33.3, "hi", 2]
> a.each {|element| puts element}
33.3
"hi"
2
=> [33.3, "hi", 2]