回顾下上节的功能改进,从用户编辑资料=》只有登录才能编辑资料=》用户只能编辑自己的资料=》用户登录后更友好的跳转功能
这节主要是实现分页和删除。
3.分页功能的实现:
这里有一点:用户列表页面只有注册用户才能访问。我们要把 index 动作加入 signed_in_user 事前过滤器。
index的视图如下:
<% provide(:title, 'All users') %>
<h1>All users</h1>
<ul class="users">
<% @users.each do |user| %>
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
</li>
<% end %>
</ul>
在 Rails 中有很多实现分页的方法,我们要使用其中一个最简单也最完善的,叫做 will_paginate。我们要使用 will_paginate 和 bootstrap-will_paginate 这两个 gem,bootstrap-will_paginate 的作用是设置 will_paginate 使用 Bootstrap 中的分页样式
修改gem如下:
gem 'will_paginate', '3.0.4'
gem 'bootstrap-will_paginate', '0.0.9'
然后是执行bundle install安装组件
此时的index视图如下:
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
<ul class="users">
<% @users.each do |user| %>
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
</li>
<% end %>
</ul>
<%= will_paginate %>
will_paginate 方法有点小神奇,在 Users 控制器的视图中,它会自动寻找名为 @users 的对象,然后显示一个分页导航链接。
$ rails console
>> User.paginate(page: 1)
User Load (1.5ms) SELECT "users".* FROM "users" LIMIT 30 OFFSET 0
(1.7ms) SELECT COUNT(*) FROM "users"
=> #<ActiveRecord::Relation [#<User id: 1,...
修改index的action:
def index
@users = User.paginate(page: params[:page])
end
这时分页功能基本实现,不过再进行下视图的重构
将
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
</li>
单独写成一个文件,
将index视图改成:
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
Rails 会把 @users 当作一系列的 User 对象,遍历这些对象,然后使用 _user.html.erb 渲染每个对象。
至此,分页功能彻底完成。
4.admin功能
先利用 $ rails generate migration add_admin_to_users admin:boolean 进行数据库的迁移
迁移文件如下:
class AddAdminToUsers < ActiveRecord::Migration
def change
add_column :users, :admin, :boolean, default: false
end
end
执行rake db:migrate 便增加了admin属性,且默认为false
5.删除用户
删除用户的链接应该只有管理员能够看到:
user部分视图如下:
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</li>
加入destroy动作:
class UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
.
.
.
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_url
end
.
.
.
end
理论上,只有管理员才能看到删除用户的链接,所以只有管理员才能删除用户。但实际上,还是存在一个严重的安全隐患:只要攻击者有足够的经验,就可以在命令行中发送 DELETE 请求,删除网站中的用户。为了保证网站的安全,我们还要限制对 destroy 动作的访问,因此我们在测试中不仅要确保只有管理员才能删除用户,还要保证其他用户不能执行删除操作
加入限制,只有admin能够执行删除操作:
before_action :admin_user, only: :destroy
加入一个private方法:
def admin_user
redirect_to(root_path) unless current_user.admin?
end
至此实现了删除功能。
回顾下这一小节的流程,实现分页的核心在于加入组建,在视图和action中适当调整
实现admin直接去迁移数据库即可
实现删除功能则进行了权限保护 只有管理员能够看到删除=》只有管理员能够进行删除
这就是有关users资源的操作。