楼主: 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
51#
 楼主| 发表于 2013-2-4 10:39 | 只看该作者
We have the follow/unfollow button under these counts, but there are a few states we need to consider. First, we don’t want to show any button if the user either is viewing their own profile or if they’re not logged in. Second, we want to display an “Unfollow” button if the user already follows this profile’s owner.
  1. <% if current_user and @user != current_user %>
  2.     <% if current_user.following? @user %>
  3.         <%= form_tag relationship_path, method: :delete do %>
  4.             <%= submit_tag "Unfollow" %>
  5.         <% end %>
  6.     <% else %>
  7.         <%= form_for @relationship do %>
  8.             <%= hidden_field_tag :followed_id, @user.id %>
  9.             <%= submit_tag "Follow" %>
  10.         <% end %>
  11.     <% end %>
  12. <% end %>
复制代码
A Rails resource is a basically a model, its associated controller, and a few other files.

Put this code just under the paragraph that holds the above spans.

The forms are the more complex parts here. First, if the current user already follows the viewed user, we’ll useform_tag to create a form that goes to therelationship_path. Of course, we can’t forget to set themethod as delete because we’re deleting a relationship.

使用道具 举报

回复
论坛徽章:
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
52#
 楼主| 发表于 2013-2-4 10:40 | 只看该作者
If the current user doesn’t follow the viewed user, we’ll create a form_for the current relationship. We’ll simply use a hidden field to determine which user to follow.
If you’re paying attention, you’ll know that something’s missing:

the ability to manipulate a relationship instance from this view. We need a Relationship instance. If the current user doesn’t already follow this user, we need to create a blank relationship.

Otherwise, we need to have a relationship on hand to delete! Back toapp/controllers/users_controller.rb, and add the following to the show method:
  1. @relationship = Relationship.where(
  2.     follower_id: current_user.id,
  3.     followed_id: @user.id
  4. ).first_or_initialize if current_user
复制代码
This is a bit different from the usual way of finding or creating a record. This initializes a blankRelationship instance if no records are found that match the where parameters. Of course, we only want to do this if there is a 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
53#
 楼主| 发表于 2013-2-4 10:41 | 只看该作者
The routes for this model are enabled by the resources : relationship line in the config/routes.rb, so we don’t have to worry about that.

Now, in app/controllers/relationships_controller.rb, we’ll start with the new method:
  1. def create
  2.         @relationship = Relationship.new
  3.         @relationship.followed_id = params[:followed_id]
  4.         @relationship.follower_id = current_user.id</p>
  5.     if @relationship.save
  6.         redirect_to User.find params[:followed_id]
  7.     else
  8.         flash[:error] = "Couldn't Follow"
  9.         redirect_to root_url
  10.     end
  11. end
复制代码
Pretty standard stuff by now, right? We’ll create the relationship, save it, and redirect back to the user’s profile.

The destroy method is also simple:
  1. def destroy
  2.     @relationship = Relationship.find(params[:id])
  3.     @relationship.destroy
  4.     redirect_to user_path params[:id]
  5. 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
54#
 楼主| 发表于 2013-2-5 12:37 | 只看该作者
Now, create another user (or four) and have a few users follow other users. You should see the text of the follow buttons change, as well as the follower / following count.
Great! Now we can commit this feature:
  1. git add .
  2. git commit -m 'Following other users is now working'
复制代码
Step 10: Creating a Few Other Pages

There are a few other simple pages that we want to add. First, let’s create a page to list all the registered users. This would be a great place to find new friends, see their pages, and eventually follow them. Logically, this should be the /users route, so we’ll use the UsersController#index method:
  1. def index
  2.     @users = User.all
  3. 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
55#
 楼主| 发表于 2013-2-5 12:38 | 只看该作者
Now, for app/views/users/index.html.erb:
  1. <div id="ribbits" class="panel left">
  2.     <h1>Public Profile</h1>
  3.     <% @users.each do |user| %>
  4.     <div class="ribbitWrapper">
  5.         <a href="<%= user_path user %>">
  6.         <img class="avatar" src="<%= user.avatar_url %>">
  7.         <span class="name"><%= user.name %></span>
  8.         </a>
  9.         @<%= user.username %>
  10.         <p>
  11.         <%= user.ribbits.size %> Ribbits
  12.         <span class="spacing"><%= user.followers.count %> Followers</span>
  13.         <span class="spacing"><%= user.followeds.count %> Following</span>
  14.         </p>
  15.         <% if user.ribbits.first %>
  16.         <p><%= user.ribbits.first.content %></p>
  17.         <% end %>
  18.     </div>
  19.     <% end %>
  20. </div>
复制代码
Finally, let’s add a link to this page to the top of our template. Let’s also add a link to the logged-in user’s profile. Right beside the “Public Ribbits” link, add:
  1. <%= link_to "Public Profiles", users_path %>
  2. <%= link_to "My Profile", 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
56#
 楼主| 发表于 2013-2-5 12:39 | 只看该作者
Next is the buddies page. This is where a user goes to view the ribbits of the people they follow; we’ll also redirect users to this page when they’re logged in and view the home page.

Strangely, finding the correct place in the code for this page is a bit tricky. After all, each page in our Rails app must be based on a method in one of our controllers. Best practice dictates that each controller has six REST methods that control a resource.

In this case, we want to view the ribbits of a subset of users, which, at least to me, seems to be a bit of an edge case. Here’s how we’ll handle it: let’s create a buddies method in the UsersController:
  1. def buddies
  2.     if current_user
  3.         @ribbit = Ribbit.new
  4.         buddies_ids = current_user.followeds.map(&:id).push(current_user.id)
  5.         @ribbits = Ribbit.find_all_by_user_id buddies_ids
  6.     else
  7.         redirect_to root_url
  8.     end
  9. 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
57#
 楼主| 发表于 2013-2-5 12:39 | 只看该作者
Obviously, there’s nothing to show if a user isn’t logged in, so we’ll check the current_user. If we’re not logged in, we redirect to the root URL (/). Otherwise, we create a new ribbit (for our new ribbit form).

We then need to find all ribbits from the current user and the people they follow.
We can use the followeds array property, and map it to only retrieve the user ids. Then, we push in the current user’s ids as well and finally retrieve the ribbits from those users.

Let’s store the template in app/views/users/buddies.html.erb; it’s very similar to our public ribbits template:
  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 class="panel left">
  13.     <h1>Buddies' Ribbits</h1>
  14.     <% @ribbits.each do |ribbit| %>
  15.         <div class="ribbitWrapper">
  16.             <a href="<%= user_path ribbit.user %>">
  17.             <img class="avatar" src="<%= ribbit.user.avatar_url %>">
  18.             <span class="name"><%= ribbit.user.name %></span>
  19.             </a>
  20.             @<%= ribbit.user.username %>
  21.             <span class="time"><%= time_ago_in_words(ribbit.created_at) %></span>
  22.             <p> <%= ribbit.content %> </p>
  23.         </div>
  24.     <% end %>
  25. </div>
复制代码

使用道具 举报

回复
论坛徽章:
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
58#
 楼主| 发表于 2013-2-6 09:13 | 只看该作者
We need to make a route for this method, in order to use it. Open config/routes.rb and add the following:
  1. get 'buddies', to: 'users#buddies', as: 'buddies'
复制代码
Now, we can go to /buddies and see the page!

There’s something else we want to do with this, however. If a logged-in user goes to the root URL, we need to redirect them to /buddies. Remember, this route is currently:
  1. def new
  2.     @user = User.new
  3. 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
59#
 楼主| 发表于 2013-2-6 09:14 | 只看该作者
Let’s change it to this:
  1. def new
  2.     if current_user
  3.         redirect_to buddies_path
  4.     else
  5.         @user = User.new
  6.     end
  7. end
复制代码
We should also add a link to the buddies page in app/views/layouts/application.html.erb:
  1. <%= link_to "Buddies' Ribbits", buddies_path %>
复制代码

使用道具 举报

回复
论坛徽章:
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
60#
 楼主| 发表于 2013-2-6 09:15 | 只看该作者
And now, we’ll commit these changes:
  1. git add .
  2. git commit -m 'added buddies page'
复制代码
Step 11 Deploying to Heroku

The last step is to deploy the application. We’ll use Heroku.

The last step is to deploy the application. We’ll use Heroku. I’m going to assume that you have a Heroku account, and that you’ve installed the Heroku toolbelt (the command line tools).

We run into a problem before we even begin! We’ve been using a SQLite database, because Rails uses SQLite by default. However, Heroku doesn’t use SQLite; it uses PostgreSQL for the database.

We have to make a change to our Gemfile, a change that actually breaks our local copy of the app (unless you install and configure a PostgreSQL server). Here’s my compromise:

I’ll show you how to do it here, and you can play with my deployed version. But you don’t have make the change on your local project.

使用道具 举报

回复

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

本版积分规则 发表回复

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