乐者为王

Do one thing, and do it well.

如何导入/导出Heroku中应用的数据

导入/导出Heroku上应用的数据需要安装Taps包:

1
gem install taps

导入数据到Heroku里:

1
heroku db:push

导出数据到本地:

1
heroku db:pull

其中导入/导出数据由config/database.yml配置设定。

Heroku还支持主机到主机的数据库传输,具体细节可以查看 http://docs.heroku.com/taps 文档。

如何联机调试Android应用

  1. 首先你需要一台开发手机,如果不是的话可以刷ROM;
  2. 在Settings -> Applications -> Development下激活USB debugging选项;
  3. 下载并安装USB驱动程序;
  4. 用USB数据线连接手机与电脑;
  5. 在AndroidManifest.xml中的<application>里添加android:debuggable="true";
  6. 然后你就可以像平常一样调试你的Android代码了。

用Rails 2.3打造简单记账应用(9)

没啥多说的,继续开始干活。

修改app/views/entries/index.html.erb为:

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
<h1>Listing entries</h1>

<table>
  <thead>
    <tr>
      <th class="center">Date</th>
      <th class="center">Amount</th>
      <th class="center">Tags</th>
      <th class="center">Comment</th>
      <th class="center">Action</th>
    </tr>
  </thead>

  <tbody>
    <% @entries.each do |entry| %>
    <tr class="<%= cycle('odd', 'even') %>">
      <td class="center"><%=h entry.effective_date %></td>
      <td class="right"><%=h number_to_currency(entry.amount) %></td>
      <td><%=h entry.tags %></td>
      <td><%=h entry.comment %></td>
      <td class="center">
        <%= link_to 'Edit', edit_entry_path(entry) %>
        <%= link_to 'Destroy', entry, :confirm => 'Are you sure?', :method => :delete %>
      </td>
    </tr>
    <% end %>
  </tbody>
</table>

<%= link_to 'New entry', new_entry_path %>

修改app/views/layouts/application.html.erb文件的内容为:

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
<!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>Qianbao: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
  <%= stylesheet_link_tag 'qianbao' %>
  <%= stylesheet_link_tag 'table' %>
</head>

<body>
  <div id="container">
    <%= render :partial => 'layouts/header' %>

    <div id="content">
      <p style="color: green"><%= flash[:notice] %></p>

      <%= yield %>
    </div>

    <%= render :partial => 'layouts/footer' %>
  </div>
</body>
</html>

新建app/views/layouts/_header.html.erb文件:

1
2
3
4
5
6
7
8
9
10
11
<div id="header">
  <%= link_to 'Home', root_path %>
  <% if logged_in? %>
    <%= link_to 'All entries', entries_path %>
    <strong>You are logged in as <%= current_user.login %></strong>
    <%= link_to 'Logout', logout_path %>
  <% else %>
    <%= link_to 'Login', login_path %>
    <%= link_to 'Sign Up', signup_path %>
  <% end %>
</div>

新建app/views/layouts/_footer.html.erb文件:

1
<div id="footer">© 2009</div>

在public/stylesheets/qianbao.css的末尾添加:

1
2
3
4
5
6
7
.center {
  text-align: center;
}

.right {
  text-align: right;
}

新建public/stylesheets/table.css,内容为:

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
table {
  border-collapse: collapse;
  text-align: left;
  width: 90%;
}

thead {
  height: 30px;
}

thead th {
  padding: 5px;
  background: #efefef;
}

tbody td {
  padding: 5px;
}

th, td {
  border: 1px solid #e6e6e6;
}

tr.odd {
  background: #fff;
}

tr.even {
  background: #f9f9f9;
}

代码下载:https://github.com/dohkoos/qianbao

如何在Heroku上部署Rails应用

要使用Heroku,必须先在其官网注册一个账号。

1、在本机上安装Heroku的gem包:

1
gem install heroku

2、提交代码到Heroku需要ssh,可以使用ssh-keygen先产生一个公钥:

1
ssh-keygen -t rsa

3、然后通过下面的命令把公钥加入到Heroku:

1
heroku keys:add

4、创建Rails项目并加入Git版本控制:

1
2
3
4
5
rails appname  # 不要使用MySQL数据库,因为Heroku暂时还不支持它
cd appname
git init
git add .
git commit -m "Initial project"

5、在Heroku上创建这个项目:

1
heroku create [appname]

注意:在创建项目时会要求输入Email和密码(即注册Heroku时输入的Email和密码),以便创建~/.heroku/credentials文件,这个文件记录了你输入的用户名和密码。

如果已经在Heroku上创建了这个项目,那么可以使用下列命令来增加一个远程服务器端,以后提交代码的时候只需要使用heroku别名即可:

1
git remote add heroku git@heroku.com:appname.git

6、将本地的代码部署到Heroku上:

1
git push heroku master

7、最后做一个数据库迁移:

1
heroku rake db:migrate

现在就可以在浏览器里输入http://appname.herokuapp.com来访问你的应用了。

用Rails 2.3打造简单记账应用(8)

今天发现一个问题,收入/支出金额在储存到数据库后小数点后面的数字不见了,经过检查发现是因为amount字段的类型为decimal(10, 0)。

Rails的迁移任务还真是好用,建一个修改列数据类型的migration就能做到。

1
script/generate migration change_amount_on_entries

然后修改该迁移任务的内容为:

1
2
3
4
5
6
7
8
9
class ChangeAmountOnEntries < ActiveRecord::Migration
  def self.up
    change_column :entries, :amount, :decimal, :precision => 8, :scale => 2
  end

  def self.down
    change_column :entries, :amount, :decimal
  end
end

最后执行一下迁移任务就可以了:

1
rake db:migrate

代码下载:https://github.com/dohkoos/qianbao

用Rails 2.3打造简单记账应用(7)

经过这几天的不断完善,记账应用越来越让人心情愉快了。不过要是能给应用加上忘记密码的功能就更好了。

创建迁移任务,在users数据表中加入一个字段用来储存修改密码时的重置码:

1
script/generate migration add_password_reset_code_to_users

执行上面的命令后就可以在db/migrate目录下看到如下格式的迁移文件:

1
20091214171949_add_password_reset_code_to_users.rb

打开它,将它的内容改为:

1
2
3
4
5
6
7
8
9
class AddPasswordResetCodeToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :password_reset_code, :string, :limit => 40
  end

  def self.down
    remove_column :users, :password_reset_code
  end
end

执行迁移任务更新数据表users:

1
rake db:migrate

然后打开config/routes.rb文件,在里面增加两个映射:

1
2
map.forgot_password '/forgot_password', :controller => 'users', :action => 'forgot_password'
map.reset_password '/reset_password/:reset_code', :controller => 'users', :action => 'reset_password'

另外还要创建两个视图文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# app/views/users/forgot_password.html.erb
<h1>Password Reset Request</h3>

<p>
  Enter your email address that we have on our file and click send.<br />
  We will send you a password reset link email to your email address.
</p>

<% form_for :user, :url => { :action => 'forgot_password' } do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </p>
  <p>
    <%= f.submit 'Send' %>
  </p>
<% end %>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# app/views/users/reset_password.html.erb
<h1>Reset Password</h1>

<% form_for :user, :url => { :action => 'reset_password' } do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </p>
  <p>
    <%= f.label :password_confirmation 'Confirm password' %><br />
    <%= f.password_field :password_confirmation %>
  </p>
  <p>
    <%= f.submit 'Reset password' %>
  </p>
<% end %>

然后就是在app/views/sessions/new.html.erb的最下面加上:

1
<%= link_to 'Forgot password?', forgot_password_path %>

在app/controllers/users_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
def forgot_password
  return unless request.post?
  if @user = User.find_by_email(params[:user][:email])
    @user.forgot_password
    @user.save
    flash[:notice] = "A password reset link has been sent to your email address"
    redirect_back_or_default('/')
  else
    flash[:alert] = "Could not find a user with that email address"
  end
end

def reset_password
  @user = User.find_by_password_reset_code(params[:reset_code])
  return if @user unless params[:user]

  new_password = params[:user][:password]
  new_password_confirmation = params[:user][:password_confirmation]

  if (new_password && new_password_confirmation &&
      !new_password.blank? && !new_password_confirmation.blank?)
    @user.reset_password(new_password, new_password_confirmation)
    if @user.save
      flash[:notice] = "Password reset success."
      redirect_back_or_default('/')
    else
      flash[:error] = "Password reset failed."
    end
  else
    flash[:error] = "Password mismatch"
  end
end

再创建两个邮件模板:

1
2
3
4
5
# app/views/user_mailer/forgot_password.html.erb
Dear <%=h @user.login %>,

  We have had a request to reset your password, please visit<br />
  <%=h @url %>
1
2
3
4
5
# app/views/user_mailer/reset_password.html.erb
Your have reset the password for your account successfully.

  Username: <%=h @user.login %>
  Password: <%=h @user.password %>

下一步是打开app/models/user.rb,在它底部protected关键字的后面添加下面的代码:

1
2
3
def make_password_reset_code
  self.password_reset_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by {rand}.join)
end

然后在protected关键字的上面添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def forgot_password
  @forgotten_password = true
  self.make_password_reset_code
end

def reset_password(new_password, new_password_confirmation)
  # First update the password_reset_code before setting the
  # reset_password flag to avoid duplicate email notifications.
  self.password_reset_code = nil
  self.password = new_password
  self.password_confirmation = new_password_confirmation
  @reset_password = true
end

def recently_forgot_password?
  @forgotten_password
end

def recently_reset_password?
  @reset_password
end

接着来配置mailer发送通知邮件,打开app/models/user_mailer.rb加上:

1
2
3
4
5
6
7
8
9
10
def forgot_password(user)
  setup_email(user)
  @subject    += 'You have requested to change your password'
  @body[:url]  = "http://#{HOST}/reset_password/#{user.password_reset_code}"
end

def reset_password(user)
  setup_email(user)
  @subject    += 'Your password has been reset.'
end

最后打开app/models/user_observer.rb修改after_save方法为:

1
2
3
4
5
def after_save(user)
  UserMailer.deliver_activation(user) if user.recently_activated?
  UserMailer.deliver_forgot_password(user) if user.recently_forgot_password?
  UserMailer.deliver_reset_password(user) if user.recently_reset_password?
end

代码下载:https://github.com/dohkoos/qianbao

用Rails 2.3打造简单记账应用(6)

调整后的entries页面就是不一样,感觉清爽多了。现在让我们添加几条测试数据吧!进入new页面,感觉似乎少了点什么。对了,怎么没有消费发生的具体时间呢?还是先把这个给加上吧。

执行下面的命令,创建一个迁移任务,添加date类型的effective_date字段到entries中:

1
2
script/generate migration add_effective_date_to_entries effective_date:date
rake db:migrate

然后修改app/views/entries/index.html.erb以显示该字段:

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
<h1>Listing entries</h1>

<table>
  <tr>
    <th>Date</th>
    <th>Amount</th>
    <th>Tags</th>
    <th>Comment</th>
    <th>Action</th>
  </tr>

  <% @entries.each do |entry| %>
  <tr>
    <td><%=h entry.effective_date %></td>
    <td><%=h entry.amount %></td>
    <td><%=h entry.tags %></td>
    <td><%=h entry.comment %></td>
    <td>
      <%= link_to 'Edit', edit_entry_path(entry) %>
      <%= link_to 'Destroy', entry, :confirm => 'Are you sure?', :method => :delete %>
    </td>
  </tr>
  <% end %>
</table>

<%= link_to 'New entry', new_entry_path %>

修改new和edit页面,加上一个effective_date文本字段:

1
2
3
4
5
6
7
<% form_for(@entry) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :effective_date %><br />
    <%= f.date_select :effective_date %>
  </p>

录入数据后发现记录是全局的,也就是说A用户添加的记录B用户也能看到,这是个问题。

用户和记录是一对多的关系,可以通过以下步骤把它们关联起来。

1
2
script/generate migration add_user_id_to_entries user_id:integer
rake db:migrate

修改app/models/user.rb,添加以下代码:

1
has_many :entries, :dependent => :destroy

修改app/models/entry.rb,加入下面的语句:

1
belongs_to :user

另外还要修改app/controllers/entries_controller.rb文件,修正由scaffold生成代码所带来的查询问题。

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
class EntriesController < ApplicationController
  before_filter :login_required

  def index
    @entries = current_user.entries.find(:all)

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

  def new
    @entry = Entry.new

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

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

  def create
    @entry = Entry.new(params[:entry])
    @entry.user = current_user

    respond_to do |format|
      if @entry.save
        flash[:notice] = 'Entry was successfully created.'
        format.html { redirect_to(entries_url) }
        format.xml  { head :ok }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @entry.errors, :status => :unprocessable_entity }
      end
    end
  end

  def update
    @entry = current_user.entries.find(params[:id])

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

  def destroy
    @entry = current_user.entries.find(params[:id])
    @entry.destroy

    respond_to do |format|
      format.html { redirect_to(entries_url) }
      format.xml  { head :ok }
    end
  end
end

代码下载:https://github.com/dohkoos/qianbao

用Rails 2.3打造简单记账应用(5)

虽然在前面已经调整了记账应用的页面流程,但在登录系统进入entries页面后却没有登出的链接,这次就来把这个完成。同时也给entries页面加上一个三行两列的布局,使之看上去更像一个应用。

在public/stylesheets下加入qianbao.css,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#container {
  width: 960px;
  margin: 5px auto;
}

#header {
  height: 2.5em;
  border-bottom: 1px solid #ccc;
}

#content {
}

#footer {
  border-top: 1px solid #ccc;
  text-align: center;
}

将app/views/layouts/目录下的entries.html.erb改名为application.html.erb,并修改文件内容为:

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
<!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>Qianbao: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
  <%= stylesheet_link_tag 'qianbao' %>
</head>

<body>
  <div id="container">
    <div id="header">
      <%= link_to 'Home', root_path %>
      <% if logged_in? %>
        <%= link_to 'All entries', entries_path %>
        <strong>You are logged in as <%=h current_user.login %></strong>
        <%= link_to 'Logout', logout_path %>
      <% else %>
        <%= link_to 'Login', login_path %>
        <%= link_to 'Sign up', signup_path %>
      <% end %>
    </div>

    <div id="content">
      <p style="color: green"><%= flash[:notice] %></p>

      <%= yield %>
    </div>

    <div id="footer">© 2009</div>
  </div>
</body>
</html>

清理app/views/home/index.html.erb的内容,回归原始:

1
<h1>Welcom to Qianbao App!</h1>

代码下载:https://github.com/dohkoos/qianbao

用Rails 2.3打造简单记账应用(4)

今天我们来继续完善我们的记账应用。

首先,修改app/views/home/index.html.erb为如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
<h1>Welcom to Qianbao App!</h1>

<% if logged_in? %>
  <p><strong>You are logged in as <%=h current_user.login %></strong></p>
  <p><%= link_to 'Logout', logout_path %></p>
<% else %>
  <p><strong>You are currently not logged in.</strong></p>
  <p>
    <%= link_to 'Login', login_path %> or
    <%= link_to 'Sign up', signup_path %>
  </p>
<% end %>

要在视图中使用logged_in?和current_user这两个帮助器方法,还需要在app/controllers/application_controller.rb中增加引入AuthenticatedSystem语句:

1
2
3
4
5
6
7
8
9
class ApplicationController < ActionController::Base
  include AuthenticatedSystem

  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details

  # Scrub sensitive parameters from your log
  # filter_parameter_logging :password
end

否则会报告下面的错误:

1
undefined method 'logged_in?'

既然在ApplicationController中已经包含了该模块,那么其它控制器中的也就可以删除了。

然后创建app/views/users/create.html.erb文件:

1
2
3
4
5
6
7
8
9
10
11
<h1>Please confirm your registration!</h1>

<p>
  A mail has been sent to <%= @user.email %> with instructions to activate your account.
  <li>
    If your email is not valid, you must <%= link_to "Sign up", signup_path %> again and provide a valid email address.
  </li>
  <li>
    If you don't recieve an email, check your bulk or trash folder, as your spam filter may have inadvertantly caught the registration email.
  </li>
</p>

同时注释掉app/controllers/users_controller.rb中create方法中的这行代码:

1
redirect_back_or_default('/')

这样当用户注册成功后就不会重定向到首页,而是显示提醒用户收取激活帐号邮件的页面。

另外,还需要把entries保护起来,不能让未登录的用户访问。可以在app/controllers/entries_controller.rb中添加一个before_filter做到:

1
2
3
4
5
6
class EntriesController < ApplicationController
  before_filter :login_required

  # GET /entries
  # GET /entries.xml
  def index

还要将登录后的页面改成entries列表,这需要将app/controllers/sessions_controller.rb中create方法下的:

1
redirect_back_or_default('/')

改为

1
redirect_back_or_default('/entries')

最后,还要调整下entries各个页面之间的流转顺序,把show这个页面去掉,使得在添加或更新记录后就直接跳到entries列表,而不再是show页面。

  1. 先将app/views/entries/show.html.erb删除;
  2. 删除app/views/entries/index.html.erb中的show链接;
  3. 删除app/views/entries/edit.html.erb中的show链接;
  4. 然后删除app/controllers/entries_controller.erb中的show方法;
  5. 再修改app/controllers/entries_controller.erb中的update和create方法为以下代码:
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
def create
  @entry = Entry.new(params[:entry])
  respond_to do |format|
    if @entry.save
      flash[:notice] = 'Entry was successfully created.'
      format.html { redirect_to(entries_url) }
      format.xml  { head :ok }
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @entry.errors, :status => :unprocessable_entity }
    end
  end
end

def update
  @entry = Entry.find(params[:id])
  respond_to do |format|
    if @entry.update_attributes(params[:entry])
      flash[:notice] = 'Entry was successfully updated.'
      format.html { redirect_to(entries_url) }
      format.xml  { head :ok }
    else
      format.html { render :action => "edit" }
      format.xml  { render :xml => @entry.errors, :status => :unprocessable_entity }
    end
  end
end

代码下载:https://github.com/dohkoos/qianbao

用Rails 2.3打造简单记账应用(3)

这次要给应用加上一个认证系统(注册、激活、登录、登出)。当用户输入注册信息时,必须输入有效的邮箱地址,注册成功后,用户并不能立即登录系统,而是要登录注册时输入的邮箱,通过该邮箱内的激活邮件来激活账户。通过这种方式可以防止用户的恶意注册。

restful_authentication是一个支持Rails 2.0的认证系统插件,它为你生成REST风格的认证系统模板,除了提供最基本的用户注册登录登出功能外,还有一个可选的邮件激活功能。只要一个命令,它就为你生成了User模型、管理注册和登录的控制器、相应的视图页面、mailer等等。

安装插件和生成框架代码

1
2
3
script/plugin install git://github.com/technoweenie/restful-authentication.git restful_authentication
script/generate authenticated user sessions --include-activation
rake db:migrate

--include-activation选项决定是否生成向新注册用户发送激活码邮件的代码。

如果你想你的URL看起来更符合惯例一些,那么可以在config/routes.rb中添加:

1
2
3
map.signup '/signup', :controller => 'users', :action => 'new'
map.login '/login', :controller => 'sessions', :action => 'new'
map.logout '/logout', :controller => 'sessions', :action => 'destroy'

因为使用了--include-activation选项,所以还要在config/routes.rb中增加以下映射:

1
2
map.activate '/activate/:activation_code',
             :controller => 'users', :action => 'activate', :activation_code => nil

最后,还需要添加一个observer到config/environment.rb的Rails::Initializer块中:

1
config.active_record.observers = :user_observer

设置ActionMailer,在config/environments/development.rb中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address => "smtp.example.com",
  :port => 25,
  :domain => "example.com",
  :authentication => :login,
  :user_name => "yourname@example.com",
  :password => "yourpassword"
}
config.action_mailer.default_charset = "utf-8"

HOST = "localhost:3000"
ADMINEMAIL = "yourname@example.com"

打开app/models/user_mailer.rb,修改

1
2
3
4
@body[:url]  = "http://YOURSITE/activate/#{user.activation_code}"
@body[:url]  = "http://YOURSITE/"
@subject     = "[YOURSITE] "
@from        = "ADMINEMAIL"

为以下代码:

1
2
3
4
@body[:url]  = "http://#{HOST}/activate/#{user.activation_code}"
@body[:url]  = "http://#{HOST}/"
@subject     = "[#{HOST}] "
@from        = "#{ADMINEMAIL}"

如果出现以下错误信息,那么可能是smtp_settings中的domain没有填写:

1
2
3
4
Net::SMTPSyntaxError (500 Error: bad syntax):
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:679:in 'check_response'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:652:in 'getok'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:622:in 'helo'

user_mailer.rb中的ADMINEMAIL必须是一个有效的邮件账号,否则会出现:

1
2
3
4
Net::SMTPFatalError (550 Invalid User):
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:679:in 'check_response'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:652:in 'getok'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:630:in 'mailfrom'

代码下载:https://github.com/dohkoos/qianbao