Ruby on Rails 初學入門(1) - 快速建立Blog (CRUD)

大家對 RoR 的印象應該是開發很快, 可以很快的把雛型建立出來.

但是 Rails 的改版變動都非常大, 之前 10分鐘建立 Blog 的影片 和 目前市面上的書都是 Rails 1.x 版, 現在都是使用 2.x 版, 照著書上做的話, 會有一堆錯誤(程式都不會動), 於是來寫幾篇紀錄摸索的過程.

在此假設您已經建好基本環境, 並且知道 Ruby 的語法, 若不清楚, 可以參考下述兩篇:

快速建立 Blog 步驟

  1. 建立 Database blog
  2. 建立 Table posts (必須要用複數)
  3. 建立 Rails project
  4. 使用 scaffold 快速產生 CRUD
  5. 修改 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, 步驟如下:

  1. cd /var/www
  2. rails blog # 這樣子就會於 /var/www/blog 產生 rails 所需檔案/結構
  3. rm public/index.html # 刪除預設首頁, 不刪掉就不會其它程式
  4. vim config/database.yml

    將 database: blog_development 修改成 database: blog

使用 scaffold 快速產生 CRUD

使用 scaffold 快速產生 CRUD 程式, 步驟如下:

  1. cd /var/www/blog
  2. 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 規則

  1. cd /var/www/blog
  2. 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.new

    respond_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.destroy

    respond_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" xml:lang="en" lang="en">
    <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>

相關文章

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

在〈Ruby on Rails 初學入門(1) - 快速建立Blog (CRUD)〉中有 11 則留言

  1. 您好
    我不太懂您的意思
    我是用esclipes 來使用jruby on rail的
    因為我還是新手
    list和edit是甚磨意思啊?

  2. 不好意思
    可能我的表達不夠好
    我知道他是剪下貼上
    而我看不懂他是如何切換如您所說的List和Edit畫面的?
    謝謝

  3. 真的很不好意思一直打擾您
    我看影片中他也都沒作什麼動作就直接切過去了
    我跟著影片作,然後停再他做的檔案上
    但我真的找不到哪裡可以切換的地方耶>.

  4. 而他也沒有分list檔還是edit檔可以切換
    影片4:45-4:48秒也是同樣的情況
    光要解決這個問題就已經花了兩天了>

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料