大家對 RoR 的印象應該是開發很快, 可以很快的把雛型建立出來.
但是 Rails 的改版變動都非常大, 之前 10分鐘建立 Blog 的影片 和 目前市面上的書都是 Rails 1.x 版, 現在都是使用 2.x 版, 照著書上做的話, 會有一堆錯誤(程式都不會動), 於是來寫幾篇紀錄摸索的過程.
在此假設您已經建好基本環境, 並且知道 Ruby 的語法, 若不清楚, 可以參考下述兩篇:
快速建立 Blog 步驟
- 建立 Database blog
- 建立 Table posts (必須要用複數)
- 建立 Rails project
- 使用 scaffold 快速產生 CRUD
- 修改 routes 將首頁指向 posts/index
建立 Database / Table
照理說應該要用 db:migrate, 邊寫邊把 Table 欄位等建立出來, 不過剛開始還是先照傳統方法來做比較容易懂.
CREATE DATABASE blog;
use blog;
CREATE TABLE `posts` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(200),
`content` text,
`created_at` datetime default NULL,
`updated_at` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
註:
- id 是必須的(Rails 規定 Table 都需要建立此欄位)
- created_at: Rails 會自動幫此欄位填入建立日期
- created_at: Rails 會自動幫此欄位填入修改日期
建立 Rails Project
假設是要建立於 /var/www/blog, 步驟如下:
- cd /var/www
- rails blog # 這樣子就會於 /var/www/blog 產生 rails 所需檔案/結構
- rm public/index.html # 刪除預設首頁, 不刪掉就不會其它程式
- vim config/database.yml
將 database: blog_development 修改成 database: blog
使用 scaffold 快速產生 CRUD
使用 scaffold 快速產生 CRUD 程式, 步驟如下:
- cd /var/www/blog
- script/generate scaffold post id:integer title:string content:text created_at:datetime # 把頁面想要秀/修改的資訊都列出來, Table 名稱於此處是用單數 (若前面沒建 DB 也可以跑這步驟, 查看修改 db/migrate/001_create_posts.rb, 再 rake db:migrate 也會建立 DB.)
scaffold 會建立下述檔案/資料:
Controller
- app/controllers/posts_controller.rb
Model
- app/models/post.rb
View
- app/views/posts # 目錄
- app/views/posts/index.html.erb
- app/views/posts/show.html.erb
- app/views/posts/new.html.erb
- app/views/posts/edit.html.erb
- app/views/layouts/posts.html.erb
View Style
- public/stylesheets/scaffold.css
Helper
- app/helpers/posts_helper.rb
Test
- test/unit/post_test.rb
- test/fixtures/posts.yml
- test/functional/posts_controller_test.rb
Database migrate
- db/migrate/001_create_posts.rb
config/routes.rb
- map.resources :posts # 檔案上方會加入此行
修改 routes 將首頁指向 posts/index
- vim config/routes.rb # 加入下述內容
map.root :controller => "posts"
到此就可以於 http://DOMAIN_NAME/ 或 http://DOMAIN_NAME/posts/ 執行 新增/刪除/修改/查詢(CRUD) 的動作, 簡易的 Blog 就算完成囉~
查看有哪些 routes 規則
- cd /var/www/blog
- rake routes # 會列出現在的 routes 的規則有哪些
Scaffold 產生的程式內容
在此將 Controller / Model / View scaffold 的檔案內容先列出來. (在初學時, 常會需要參考 scaffold 怎麼寫的, 列出來參考也比較容易懂)
Controller
- app/controllers/posts_controller.rb
class PostsController < ApplicationController
# GET /posts
# GET /posts.xml
def index
@posts = Post.find(:all)respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
end
end# GET /posts/1
# GET /posts/1.xml
def show
@post = Post.find(params[:id])respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @post }
end
end# GET /posts/new
# GET /posts/new.xml
def new
@post = Post.newrespond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @post }
end
end# GET /posts/1/edit
def edit
@post = Post.find(params[:id])
end# POST /posts
# POST /posts.xml
def create
@post = Post.new(params[:post])respond_to do |format|
if @post.save
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to(@post) }
format.xml { render :xml => @post, :status => :created, :location => @post }
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end# PUT /posts/1
# PUT /posts/1.xml
def update
@post = Post.find(params[:id])respond_to do |format|
if @post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to(@post) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
@post = Post.find(params[:id])
@post.destroyrespond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
end
Model
- app/models/post.rb
class Post < ActiveRecord::Base
end
View
- app/views/posts/index.html.erb # 全部列表
<h1>Listing posts</h1><table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Content</th>
<th>Created at</th>
</tr><% for post in @posts %>
<tr>
<td><%=h post.id %></td>
<td><%=h post.title %></td>
<td><%=h post.content %></td>
<td><%=h post.created_at %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table><br />
<%= link_to 'New post', new_post_path %>
- app/views/posts/show.html.erb # 查詢某筆資料
<p>
<b>Id:</b>
<%=h @post.id %>
</p><p>
<b>Title:</b>
<%=h @post.title %>
</p><p>
<b>Content:</b>
<%=h @post.content %>
</p><p>
<b>Created at:</b>
<%=h @post.created_at %>
</p><%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %> - app/views/posts/new.html.erb # 新增
<h1>New post</h1>
<%= error_messages_for :post %>
<% form_for(@post) do |f| %>
<p>
<b>Id</b><br />
<%= f.text_field :id %>
</p><p>
<b>Title</b><br />
<%= f.text_field :title %>
</p><p>
<b>Content</b><br />
<%= f.text_area :content %>
</p><p>
<b>Created at</b><br />
<%= f.datetime_select :created_at %>
</p><p>
<%= f.submit "Create" %>
</p>
<% end %><%= link_to 'Back', posts_path %>
- app/views/posts/edit.html.erb # 編輯
<h1>Editing post</h1>
<%= error_messages_for :post %>
<% form_for(@post) do |f| %>
<p>
<b>Id</b><br />
<%= f.text_field :id %>
</p><p>
<b>Title</b><br />
<%= f.text_field :title %>
</p><p>
<b>Content</b><br />
<%= f.text_area :content %>
</p><p>
<b>Created at</b><br />
<%= f.datetime_select :created_at %>
</p><p>
<%= f.submit "Update" %>
</p>
<% end %><%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %> - app/views/layouts/posts.html.erb # posts html layout 的 template 檔.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Posts: <%= controller.action_name %></title>
<%= stylesheet_link_tag 'scaffold' %>
</head>
<body><p style="color: green"><%= flash[:notice] %></p>
<%= yield %>
</body>
</html>