这节主要解决关注功能的实现。
现在用户已经有关注的人和粉丝了,我们要更新一下用户资料页面和首页,把这些变动显示出来。首先,我们要创建一个关注和取消关注的表单,然后再创建显示被关注用户列表和粉丝列表的页面。
首先我们把 following 和 folloers 动作加入 Users 控制器的路由中:
- SampleApp::Application.routes.draw do
- resources :users do
- member do
- get :following, :followers
- end
- end
- .
- .
- .
- end
路由设置中使用的 member 方法作用是,设置这两个动作对应的 URL 地址中应该包含用户的 id。类似地,我们还可以使用 collection 方法,但 URL 中就没有用户 id 了。
上述代码生成的具名路由为:
- HTTP 请求 URL 动作 具名路由
- GET /users/1/following following following_user_path(1)
- GET /users/1/followers followers followers_user_path(1)
然后是编写各种表单。
显示关注数量统计的局部视图
app/views/shared/_stats.html.erb
- <% @user ||= current_user %>
- <div class="stats">
- <a href="<%= following_user_path(@user) %>">
- <strong id="following" class="stat">
- <%= @user.followed_users.count %>
- </strong>
- following
- </a>
- <a href="<%= followers_user_path(@user) %>">
- <strong id="followers" class="stat">
- <%= @user.followers.count %>
- </strong>
- followers
- </a>
- </div>
在首页中加入:
- <section>
- <%= render 'shared/stats' %>
- </section>
关注和取消关注表单
app/views/users/_follow_form.html.erb
- <% unless current_user?(@user) %>
- <div id="follow_form">
- <% if current_user.following?(@user) %>
- <%= render 'unfollow' %>
- <% else %>
- <%= render 'follow' %>
- <% end %>
- </div>
- <% end %>
添加Relationships的路由:
- resources :relationships, only: [:create, :destroy]
关注用户的表单和取消关注的表单:
app/views/users/_follow.html.erb 和 app/views/users/_unfollow.html.erb
- <%= form_for(current_user.relationships.build(followed_id: @user.id)) do |f| %>
- <div><%= f.hidden_field :followed_id %></div>
- <%= f.submit "Follow", class: "btn btn-large btn-primary" %>
- <% end %>
- <%= form_for(current_user.relationships.find_by(followed_id: @user),
- html: { method: :delete }) do |f| %>
- <%= f.submit "Unfollow", class: "btn btn-large" %>
- <% end %>
在用户资料show页面加入:
- <section>
- <%= render 'shared/stats' %>
- </section>
为了实现查看粉丝和关注人的功能,在user的控制器中实现:
- def following
- @title = "Following"
- @user = User.find(params[:id])
- @users = @user.followed_users.paginate(page: params[:page])
- render 'show_follow'
- end
- def followers
- @title = "Followers"
- @user = User.find(params[:id])
- @users = @user.followers.paginate(page: params[:page])
- render 'show_follow'
- end
最后均转向show_follow,实现如下:
app/views/users/show_follow.html.erb
- <% provide(:title, @title) %>
- <div class="row">
- <aside class="span4">
- <section>
- <%= gravatar_for @user %>
- <h1><%= @user.name %></h1>
- <span><%= link_to "view my profile", @user %></span>
- <span><b>Microposts:</b> <%= @user.microposts.count %></span>
- </section>
- <section>
- <%= render 'shared/stats' %>
- <% if @users.any? %>
- <div class="user_avatars">
- <% @users.each do |user| %>
- <%= link_to gravatar_for(user, size: 30), user %>
- <% end %>
- </div>
- <% end %>
- </section>
- </aside>
- <div class="span8">
- <h3><%= @title %></h3>
- <% if @users.any? %>
- <ul class="users">
- <%= render @users %>
- </ul>
- <%= will_paginate %>
- <% end %>
- </div>
- </div>