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]