`

Ruby on Rails注册激活系统

阅读更多

rails ruby ruby on rails敏捷开发最佳实践 李刚 rails的邮件抽象层 注册激活系统

        现在好像Ruby on Rails越来越流行了,我也开始研究一下这门新兴的热门技术。今天刚看到网上推荐了一本新书《Ruby on Rails敏捷开发最佳实践》,第一作者就是颇受好评的《struts2权威指南》的作者李刚,而第二作者据说是位在外企工作很有ror经验的人士。我读了一下试读部分,果然清晰易懂,又讲解得十分透彻,而所举的例子也非常实用。
         下面,我摘录了书中关于注册激活系统的部分,是Rails的邮件抽象层中的内容。这个例子对于以后做通过邮件来激活注册这样的项目时,就能派上用场了。


(1) 基本注册功能
当用户注册一个账户时,实际上就等同于向底层数据表增加一条记录,因此本应用必须有持久层支持。本示例应用的注册功能需要一个数据表支持,该数据表用于保存系统的所有注册账户。下面是本应用的数据库脚本:

Sql代码  

drop database if exists regist_development;   

  

create database regist_development;   

  

use regist_development;   

  

--创建用户表  

  

create table users (   

10   

11     id int not null auto_increment,   

12   

13     name varchar(100) not null unique,   

14   

15     pass varchar(100) not null,   

16   

17     email varchar(150) not null,   

18   

19     active_code varchar(255),   

20   

21     is_activated boolean,     

22   

23     primary key (id)   

24   

25 );  



上面创建了一个users数据表,该数据表里保存了用户名、密码、E-mail、激活码和是否激活等5个数据列。前三个数据列的作用非常清晰,此处不再赘述。激活码列用于保存用户刚刚注册时系统生成的注册码,这个注册码将通过邮件发送给用户,系统正是通过比较用户输入的注册码和这个注册码是否相等,从而决定是否可以激活用户。

上面的users数据表对应的持久化类是User,这个持久化类的代码非常简单,只是增加了一些Model校验功能。下面是User类的代码:

Ruby代码  

26 class User < ActiveRecord::Base   

27   

28     def validate   

29   

30         #验证name不能为空      

31   

32         errors.add("", "用户名只能是字母、数字或下划线,且长度必须为420")   

33   

34             unless name=~ /^\w{4,20}$/   

35   

36         #验证name不能是一个数据库中已经存在的名字   

37   

38         errors.add("", "用户名不能重复,您选择的用户名已经存在")   

39   

40             unless User.find_by_name(name).nil?   

41   

42         #验证password不能为空   

43   

44         errors.add("", "密码只能是字母或数字,且长度必须为420")    

45   

46             unless pass =~ /^[a-zA-Z0-9]{4,20}$/   

47   

48         #验证e-mail规则   

49   

50         errors.add("", "电子邮件必须匹配电子邮件规则")   

51   

52             unless email =~ /^\w+@\w+.[a-zA-Z]{2,6}$/   

53   

54     end  

55   

56 end  


提供了上面的User Model之后,处理用户注册就非常简单了,只需要提供一个注册表单,这个表单里包含用户注册的基本信息即可。下面是用户注册的表单页代码:

Ruby代码  

57 <b>请输入您的注册信息</b><br>   

58   

59 <b>注意:请务必输入有效的邮箱用于接收激活邮件</b><br>   

60   

61 <%= error_messages_for :user %>   

62   

63 <% form_for :user, @user, :url => { :action => "pro_regist" } do |f| %>   

64   

65 用户名:<%= f.text_field :name %><br/>   

66   

67  码:<%= f.password_field :pass %><br/>   

68   

69 Email<%= f.text_field :email %><br/>   

70   

71 <%= submit_tag("注册")%>   

72   

73 <% end %>  


当用户单击注册按钮时,将会把表单提交到pro_regist Action。这个Action也非常简单,它只需调用该User类的create方法向users数据表中增加一条记录即可。下面是处理用户注册的Action代码:

Ruby代码  

74 处理用户登录  

75   

76 def pro_regist   

77   

78     #创建一个新的user对象  

79   

80     @user = User.new(params[:user])   

81   

82     # 以当前时间来随机生成激活码  

83   

84     @user.active_code = rand(Time.now.to_i).to_s   

85   

86     # 设置用户开始处于未激活状态  

87   

88     @user.is_activated = false  

89   

90     #如果user对象能成功地保存进数据库  

91   

92     if @user.save then  

93   

94         flash[:notice] = '您已经注册成功'  

95   

96         flash[:name] = @user.name   

97   

98         # 发送邮件  

99   

100         ActivateMail.deliver_sent(@user)   

101   

102         redirect_to :action => 'success'  

103   

104     # 保存失败  

105   

106     else  

107   

108         render :action => 'index'  

109   

110     end  

111   

112 end  


上面的Action方法的实现与普通注册Action代码大致相似,不同的是上面的Action代码需要调用ActivateMail.deliver_sent(@user)代码来发送邮件。这行代码调用ActivateMail Model里的sent方法来发送激活邮件,这也就是本应用实现用户激活的重点。


(2) 发送激活邮件
本应用需要向注册用户发送激活邮件,对于Rails应用而言,激活邮件也就是一封最普通的邮件,因此我们像开发普通邮件模块一样来实现发送激活邮件。同样,我们先使用Rails提供的邮件代码生成器来生成一个邮件模块。进入Rails应用的根路径下,输入如下命令:

生成ActivateMail邮件Model,并提供一个sent方法

ruby script/generate mail ActivateMail sent

上面的代码生成器命令会在app/models路径下生成一个activate_mail.rb文件,这个文件就是邮件发送Model,该Model里定义了一个sent方法,该方法就是发送邮件的业务逻辑方法。修改上面的sent方法,让该sent方法实现发送激活邮件的功能。修改后的sent方法代码如下:

Ruby代码  

113 定义发送邮件的业务方法  

114   

115 def sent(user)   

116   

117     # 指定邮件标题  

118   

119     @subject    = '激活邮件'  

120   

121     # 将新注册的User实例传给邮件内容模板  

122   

123     @body       = {'user'=>user}   

124   

125     # 使用用户的注册邮件作为收件人地址  

126   

127     @recipients = user.email   

128   

129     # 使用spring_test@sina.com作为发件人地址  

130   

131     @from       = 'spring_test@sina.com'  

132   

133     @sent_on    = Time.now   

134   

135     @headers    = {}   

136   

137     # 指定使用HTML格式的邮件  

138   

139     @content_type = 'text/html'  

140   

141 end  


与前面完全类似的是,我们一样采用spring_test@sina.com作为发件人地址,这就要求我们必须在config路径下的environment.rb文件中配置sina的邮件服务器。在environment.rb文件中增加如下代码:

Ruby代码  

142 ActionMailer::Base.delivery_method = :smtp  

143   

144 ActionMailer::Base.server_settings = {    

145   

146     :address => 'smtp.sina.com',   

147   

148     :port => 25,   

149   

150     :domain => 'sina.com',   

151   

152     :user_name => 'spring_test@sina.com',   

153   

154     :password => '123456',   

155   

156     :authentication => :login }   

157   

158 ActionMailer::Base.default_charset  = 'GBK'  


经过上面步骤,我们已经实现了发送激活邮件的大部分功能。还有一个必须完成的地方:我们定义sent(user)方法时,该方法为@body赋值的是一个Hash对象,这意味着我们还需要为该方法指定一个邮件模板。

当我们执行ruby script/generate mail ActivateMail sent命令时,该命令还在app\views\activate_mail路径下生成了一个sent.rhtml文件,这个模板文件的响应将作为ActivateMail.sent(user)方法发送的邮件内容。sent.rhtml模板文件的代码如下:

Ruby代码  

159 <h4><%= @user.name%>,您好!</h4>   

160   

161 请在浏览器的地址栏中输入如下地址来激活您的账户:<br/>   

162   

163 <a href='http://localhost:3000/regist/pro_activate?name=<%= @user.name%>&active_code=   

164   

165     <%= @user.active_code%>'>   

166   

167 http://localhost:3000/regist/pro_activate?name=<%= @user.name%>&active_code=   

168   

169     <%= @user.active_code%>   

170   

171 </a>  


上面的邮件模板是一个非常简单的页面,这个页面包含了一个简单的超级链接,这个超级链接将向服务器发送两个请求参数:用户名和验证码。

用户只要单击账户激活链接,就可以激活刚刚注册的账户。在还未激活用户账户之前,我们打开users数据表,看到用户刚刚注册的账户信息处于未激活状态。

当用户账户被激活后,is_activated列的值将变成1,这表明用户账户已被激活。


(3) 处理激活
用户单击激活邮件中的链接,相当于向系统的regist控制器的pro_activate Action发送一个请求,并将用户名和激活码作为请求参数,Rails应用将根据这两个请求参数来决定是否激活用户账户。下面是pro_activate Action的代码:

Ruby代码  

172 处理用户激活  

173   

174 def pro_activate   

175   

176     user = User.find_by_name(params[:name])   

177   

178     # 如果用户不为空,且用户处于未激活状态,且用户输入的激活码正确  

179   

180     if user != nil && user.is_activated == false && user.active_code == params[:active_code] then  

181   

182         # 修改激活状态  

183   

184         user.update_attribute(:is_activated , true)   

185   

186         flash[:notice] = "恭喜您,您已经成功激活了您的账户!"  

187   

188     # 如果用户已经处于激活状态  

189   

190     elsif user != nil && user.is_activated == true then  

191   

192         flash[:notice] = "您的账户已经处于激活状态,请勿重复激活!"  

193   

194     else  

195   

196         flash[:notice] = "激活失败!"  

197   

198     end  

199   

200     redirect_to :action=>'activate_result'  

201   

202 end  


上面Action先根据发送的name请求参数取出users表中对应的用户账户,然后判断取出的账户里包含的激活码与用户请求中包含的激活码请求参数是否相同。如果两个激活码相同,而且用户还未激活,系统将把用户账户的is_activated属性修改为true,即完成用户激活。如果用户的is_activated状态已经是true,则提醒用户不用重复激活账户。

当用户注册成功,并且通过激活链接来激活账户后,也就是将users数据表中对应记录行的is_activated数据列的值修改为1。  

<!--EndFragment-->
1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics