乐者为王

Do one thing, and do it well.

用Rails 3.2打造简单记账应用

Rails已经到3.2版本了,和以前的2.3版本有了很大的不同,决定把原来老版本的记账应用重新写一遍,更新部分插件。

首先是创建项目:

1
2
3
4
rails new qianbao
cd qianbao
rails g scaffold entry amount:decimal tags:string comment:text effective_date:date
rails g controller home index

删除public/index.html,在config/routes.rb中添加根路由:

1
root :to => 'home#index'

现在要给应用加上一个认证系统(注册、激活、登录、登出),这次使用devise插件实现。

在Gemfile中添加:

1
gem 'devise'

然后执行下列命令:

1
2
3
4
bundle install
rails g devise:install
rails g devise user
rails g devise:views

创建一个迁移任务,把User和Entry模型关联起来:

1
2
3
4
5
6
7
class AddUserIdToEntries < ActiveRecord::Migration
  def change
    add_column :entries, :user_id, :integer

    add_index :entries, :user_id
  end
end

修改Entry和User模型:

1
2
3
4
5
6
7
8
9
class Entry < ActiveRecord::Base
  validates :effective_date, :presence => true
  validates :amount,         :presence => true,
                             :numericality => { :greater_than => 0.0 },
                             :format => { :with => /^\d+??(?:\.\d{0,2})?$/ }
  validates :tags,           :presence => true,
                             :length => { :within => 1..255 }

  belongs_to :user
1
2
class User < ActiveRecord::Base
  has_many :entries

修改app/views/layouts/application.html.erb文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
  <% if user_signed_in? %>
    <p>
      <strong><%= link_to current_user.email, edit_user_registration_path %></strong>
      <%= link_to 'Logout', destroy_user_session_path, :method => :delete %>
    </p>
    <%= link_to "All Entries", entries_path %>
  <% else %>
    <p>
      <strong>You are currently not logged in.</strong>
      <%= link_to 'Sign in', new_user_session_path %> or
      <%= link_to 'Sign up', new_user_registration_path %>
    </p>
  <% end %>

  <%= yield %>
</body>

修改app/controller/entries_controller.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
class EntriesController < ApplicationController
  before_filter :authenticate_user!

  # GET /entries
  # GET /entries.json
  def index
    @entries = current_user.entries

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @entries }
    end
  end

  # GET /entries/1
  # GET /entries/1.json
  def show
    @entry = current_user.entries.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @entry }
    end
  end

  # GET /entries/new
  # GET /entries/new.json
  def new
    @entry = Entry.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @entry }
    end
  end

  # GET /entries/1/edit
  def edit
    @entry = current_user.entries.find(params[:id])
  end

  # POST /entries
  # POST /entries.json
  def create
    @entry = Entry.new(params[:entry])
    @entry.user = current_user

    respond_to do |format|
      if @entry.save
        format.html { redirect_to @entry, notice: 'Entry was successfully created.' }
        format.json { render json: @entry, status: :created, location: @entry }
      else
        format.html { render action: "new" }
        format.json { render json: @entry.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /entries/1
  # PUT /entries/1.json
  def update
    @entry = current_user.entries.find(params[:id])

    respond_to do |format|
      if @entry.update_attributes(params[:entry])
        format.html { redirect_to @entry, notice: 'Entry was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @entry.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /entries/1
  # DELETE /entries/1.json
  def destroy
    @entry = current_user.entries.find(params[:id])
    @entry.destroy

    respond_to do |format|
      format.html { redirect_to entries_url }
      format.json { head :no_content }
    end
  end
end

执行以下命令启动应用:

1
2
rake db:migrate
rails s

以前的版本用的CSS框架是Blueprint,这次使用比它更方便快捷的Bootstrap。Bootstrap建立在Less上,有个less-rails-bootstrap,不过在安装libv8时竟然要提示缺少Python,拜托!我用的是Ruby,要我装Python,啥意思啊!还是找个Sass版的Bootstrap吧。

下载sass-twitter-bootstrap

1
git clone https://github.com/jlong/sass-twitter-bootstrap.git

将sass-twitter-bootstrap/lib中的文件拷贝到app/assets/stylesheets/twitter目录下。然后将app/assets/stylesheets/application.css中的

1
*= require_tree .

修改为

1
*= require twitter/bootstrap

再在文件末尾添加:

1
body { padding-top: 60px; }

现在就可以使用Bootstrap来布局美化应用了。

Comments