楼主: jieforest

Building Ribbit in Rails

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
31#
 楼主| 发表于 2013-1-31 10:37 | 只看该作者
Now, fill in the form and click “Create Account.” You should be sent to the user profile, like this:



Great! Now we have our user accounts working. Let’s commit this:
  1. git add .
  2. git commit -m 'User form and profile pages'
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
32#
 楼主| 发表于 2013-1-31 10:38 | 只看该作者
Step 6: Adding Session Support

Even though we implemented the user feature, a user cannot log in just yet. So, let’s add session support next.

You may have recognized the way we’ve created user accounts.

I’ve taken this general method from Railscast episode 250. That episode also demonstrates how to create session support, and I’ll use that approach for Ribbit.

We start by creating a controller to manage our sessions. We won’t actually store sessions in the database, but we do need to be able to set and unset session variables. A controller is the correct way to do that.
  1. rails generate controller sessions new create destroy
复制代码
Here, we create a new controller, called sessions. We also tell it to generate the new, create, anddestroy methods. Of course, it won’t fill in these methods, but it will create their “shell” for us.

Now, let’s open the app/controllers/sessions_controller.rb file.

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
33#
 楼主| 发表于 2013-1-31 10:39 | 只看该作者
The new method is fine as is, but the create method needs some attention. This method executes after the user enters their credentials and clicks “Log In.” Add the following code:
  1. def create
  2.     user = User.find_by_username(params[:username])
  3.     if user && user.authenticate(params[:password])
  4.         session[:userid] = user.id
  5.         redirect_to rooturl, notice: "Logged in!"
  6.     else
  7.         flash[:error] = "Wrong Username or Password."
  8.         redirect_to root_url
  9.     end
  10. end
复制代码
We use the find_by_username method on the User class to retrieve the user with the provided username. Then, we call the authenticate method, passing it the password. This method was added as part of theuse_secure_password feature.

If the user’s credentials pass muster, we can set the user_id session variable to the user’s ID. Finally, we redirect to the root route with the message “Logged in!”.

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
34#
 楼主| 发表于 2013-1-31 10:40 | 只看该作者
If the user’s credentials fail to authenticate, we simply redirect to the root route and set the flash error message to “Username or password was wrong.“
Logging out fires the destroy method. It’s a really simple method:
  1. def destroy
  2.     session[:userid] = nil
  3.     redirect_to root_url, notice: "Logged out."
  4. end
复制代码
This code is fairly self-explanatory; just get rid of that session variable and redirect to the root.

Rails helped us out once again and added three routes for these methods, found in config/routes.rb:
  1. get "sessions/new"
  2. get "sessions/create"
  3. get "sessions/destroy"
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
35#
 楼主| 发表于 2013-1-31 10:41 | 只看该作者
We want to change the sessions/create route to POST, like this:
  1. post "sessions/create"
复制代码
We’re almost ready to add the login form to our views. But first, let’s create a helper method that allows us to quickly retrieve the currently logged-in user.

We’ll put this in the application controller so that we can access it from any view file. The path to the application controller isapp/controllers/application_controller.rb.
  1. private
  2. def current_user
  3.     @current_user ||= User.find(session[:user_id]) if session[:user_id]
  4. end
  5. helper_method :current_user
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
36#
 楼主| 发表于 2013-2-1 12:46 | 只看该作者
If no user is logged in, we use the form_tag method to create a form that posts to the seesions_create_path.

Note that we can’t use the form_for method because we don’t have an instance object for this form (like with our user object). The text_field_tag and password_field_tag methods accept the same parameters:

the name for the field as a symbol, the value for the field (nil in this case), and then an options object. We’re just setting a placeholder value here.

There’s a bit of a glitch in our session support: a user is not automatically logged in, after they create a new user account.

We can fix this by adding a single line to the create method in the UserController class. Right after the if @user.save line, add:
  1. session[:user_id] = @user.id
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
37#
 楼主| 发表于 2013-2-1 12:46 | 只看该作者
Believe it or not, the above line of code finishes the session feature. You should now be able to re-start the Rails server and log in.

Try to log out and back in again. The only difference between the two functions is the lack of the login form when you’re logged in. But we’ll add more later!

Let’s commit this:
  1. git add .
  2. git commit -m 'users are now logged in upon creation'
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
38#
 楼主| 发表于 2013-2-1 12:47 | 只看该作者
Step 7: Creating Ribbits

Now we’re finally ready to get to the point of our application: creating Ribbits (our version of tweets). We begin by creating the ribbit resource:
  1. rails g resource ribbit content:text user_id:integer
  2. rake db:migrate
复制代码
This resource only needs two fields: the actual content of the ribbit, and the id of the user who created it. We’ll migrate the database to create the new table. Then, we’ll make a few modifications to the new Ribbit model. Open app/models/ribbit.rb and add the following:
  1. class Ribbit < ActiveRecord::Base
  2.   default_scope order: 'createdat DESC'
  3.   attr_accessible :content, :userid
  4.   belongs_to :user
  5.   validates :content, length: { maximum: 140 }
  6. end
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
39#
 楼主| 发表于 2013-2-1 12:48 | 只看该作者
The default_scope call is important; it orders a list of ribbits in from the most recent to least recent. Thebelongs_to method creates an association between this Ribbit class and the User class, making our user objects have a tweets array as a property.

Finally, we have a validates call, which ensures that our ribbits don’t exceed 140 characters.

Oh, yeah: the flip side of the belongs_to statement. In the User class (app/models/user.rb), we want to add this line:
  1. has_many :ribbits
复制代码
This completes the association; now each user can have many ribbits.

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
40#
 楼主| 发表于 2013-2-2 15:58 | 只看该作者
We want users to have the ability to create ribbits from their profile page. As you’ll recall, we have a form in that template. So let’s replace that form in app/view/users/show.html.erb, as well as make a few other changes. Here’s what you should end up with:
  1. <% if current_user %>
  2. <div id="createRibbit" class="panel right">
  3.     <h1>Create a Ribbit</h1>
  4.     <p>
  5.     <%= form_for @ribbit do |f| %>
  6.         <%= f.textarea :content, class: 'ribbitText' %>
  7.         <%= f.submit "Ribbit!" %>
  8.     <% end %>
  9.     </p>
  10. </div>
  11. <% end %>
  12. <div id="ribbits" class="panel left">
  13.     <h1>Your Ribbit Profile</h1>
  14.     <div class="ribbitWrapper">
  15.         <img class="avatar" src="<%= @user.avatar_url %>">
  16.         <span class="name"><%= @user.name %></span> @<%= @user.username %>
  17.         <p>
  18.         <%= @user.ribbits.size %> Ribbits
  19.         <span class="spacing">XX Followers</span>
  20.         <span class="spacing">XX Following</span>
  21.         </p>
  22.     </div>
  23. </div>
  24. <div class="panel left">
  25.     <h1>Your Ribbits</h1>
  26.     <% @user.ribbits.each do |ribbit| %>
  27.         <div class="ribbitWrapper">
  28.             <img class="avatar" src="<%= @user.avatar_url %>">
  29.             <span class="name"><%= @user.name %></span>
  30.             @<%= @user.username %>
  31.             <span class="time"><%= time_ago_in_words(ribbit.created_at) %></span>
  32.             <p> <%= ribbit.content %> </p>
  33.         </div>
  34.     <% end %>
  35. </div>
复制代码

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表