Rails 实战——图书管理系统——图书后台
2018-03-26 09:28
471 查看
目标
建立图书管理后台,实现图书CRUD、会员系统、 “上架与下架” 一键切换,借书单。在本教程中两个符号 “*…” 中间插入的代码新增代码。
1、配置路由
设定后台图书的 CURD、前台图书的路由config/routes.rb
Rails.application.routes.draw do root 'welcome#index' * resources :users * resources :sessions resources :books namespace :admin do #使用命名空间 namespace resources :books end * # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
2、建立 Book 数据表
2.1 数据库中建立 book 数据表
$ rails g migration create_books
db/migrate/xxxx一堆数字xxxx_create_books.rb
class CreateBooks < ActiveRecord::Migration[5.1] * def change * create_table :books do |t| t.string :title t.text :text t.timestamps * end * end end
2.2 建立 book 模型
$ touch app/models/book.rb
app/models/book.rb
class Book < ApplicationRecord end
2.3 测试
终端进入 rails c (后台金手指)rails c #进入 rails 金手指 u = Book.new u.title = "Hello" u.text = "World" u.save exit #退出 rails 金手指
3、实现 Book 后台的 CRUD
3.1 Book的New
终端执行mkdir app/controllers/admin touch app/controllers/admin/books_controller.rb
配置文件 app/controllers/admin/books_controller.rb
class Admin::BooksController < ApplicationController # 使用命名空间 namespace ,class的命名使用 Admin::BooksController 格式 def new @book = Book.new end def create @book = Book.new(book_params) if @book.save #查询单个数据必须传递参数实现检索定位,例如@book redirect_to book_path(@book) #重定向 >> 图书 show 页面 else render "new" end end private #健壮参数,简化参数代码,实现 rails 预筛选安全机制。 def book_params params.require(:book).permit(:title, :text) end end
终端执行
mkdir app/views/admin/books touch app/views/admin/books/new.html.erb
配置文件 app/views/admin/books/new.html.erb
<h1>新书上架</h1> #使用命名空间 namespace ,传递参数使用数组[:admin, @book] <%= form_for [:admin, @book] do |f| %> <p> <%= f.label :title %> <%= f.text_field :title %> </p> <p> <%= f.label :text %> <%= f.text_area :text %> </p> <p> <%= f.submit "提交"%> </p> <% end %>
3.2 Book的show
修改文件 app/controllers/admin/books_controller.rbclass Admin::BooksController < ApplicationController def index @books = Book.all end * def new * end * def create * end def show @book = Book.find(params[:id]) end end
终端执行
book 后台新建的图书,要让所有人都看到,需要新建文件 app/views/books
mkdir app/views/books touch app/views/books/show.html.erb touch app/views/admin/books/index.html.erb
配置图书展示页 app/views/books/show.html.erb
<h1>图书简介</h1> <p> <strong>书名:</strong> <%= @book.title %> </p> <p> <strong>简介:</strong> <%= @book.text %> </p>
3.3 Book的edit
修改文件 app/controllers/admin/books_controller.rbclass Admin::BooksController < ApplicationController ...... * def show * end def edit @book = Book.find(params[:id]) end def update @book = Book.find(params[:id]) if @book.update(book_params) #查询某数据表所有数据,可以省略传递参数 redirect_to admin_books_path else render "edit" end end ...... end
终端执行
touch app/views/admin/books/edit.html.erb
配置文件 app/views/admin/books/edit.html.erb
<h1>图书修改</h1> <%= form_for [:admin, @book] do |f| %> <p> <%= f.label :title %> <%= f.text_field :title %> </p> <p> <%= f.label :text %> <%= f.text_area :text %> </p> <p> <%= f.submit "提交"%> </p> <% end %>
配置图书后台首页 app/views/admin/books/index.html.erb
<h1>图书馆后台</h1> <p> <%= link_to "新书上架", new_admin_book_path %> </p> <table class="table table-bordered table-hover"> <tr class="text-info"> <th>书名</th> <th>简介</th> <th>操作</th> </tr> <% @books.each do |book| %> <tr> <td><%= book.title %></td> <td><%= book.text %></td> <td> <%= link_to "显示", book_path(book) %><span style="margin-left: 5px">|</span> <%= link_to "编辑", edit_admin_book_path(book) %><span style="margin-left: 5px">|</span> </td> </tr> <% end %> </table>
3.3 Book的 delete
修改文件 app/controllers/admin/books_controller.rbclass Admin::BooksController < ApplicationController ...... * def update * end def destroy @book = Book.find(params[:id]) @book.destroy redirect_to admin_books_path end * private ...... end
修改文件 app/views/admin/books/index.html.erb
删除动作直接在后台首页执行,需要再次确认删除提示
* <%= link_to "编辑", edit_admin_book_path(book) %><span style="margin-left: 5px">|</span> <%= link_to "删除", admin_book_path(book), method: :delete, data: { confirm: "确定删除本书?"} %> * </td> * </tr> * <% end %> </table>
4、管理员可以登录后台系统
4.1 users 数据表增加 is_admin 字段
终端执行rails g migration add_is_admin_to_user
配置文件 db/migrate/xxxx一堆数字xxxx_add_is_admin_to_user.rb
class AddIsAdminToUser < ActiveRecord::Migration[5.1] * def change add_column :users, :is_admin, :boolean, deafault: false * end end
4.2 进入金手指 rails c ,手动配置管理员
rails c u = User.first u.is_admin = true u.save exit
4.3 加入管理员验证机制
修改文件 app/controllers/admin/books_controller.rbclass Admin::BooksController < ApplicationController before_action :admin_required * def index end
修改文件 app/controllers/application_controller.rb
class ApplicationController < ActionController::Base * protect_from_forgery with: :exception def admin_required if !current_user.present? redirect_to '/' , alert: "你不是管理员" #在 rails5.1环境中,消息提示未出现,之后解决 end end end
4.4 建立后台布局( layout)
修改文件 app/controllers/admin/books_controller.rbclass Admin::BooksController < ApplicationController layout "admin" * before_action :admin_required ..... end
终端执行
touch app/views/layouts/admin.html.erb #建立后台布局文件
配置文件 app/views/layouts/admin.html.erb
<!DOCTYPE html> <html> <head> <title>图书馆 后台</title> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> </head> <body> <div class="container"> <%= render "common/navbar" %> <div class="row"> <div class="col-md-2"> <ul class="nav nav-pills nav-stacked" style="max-width: 300px;"> <li> <%= link_to("图书", admin_books_path) %> </li> </ul> </div> <div class="col-md-10"> <%= yield %> </div> </div> </div> </body> </html>
git add . git commit -m "only admin can access backend panel"
5、图书状态“上架与下架”一键更改
5.1 路由配置
设定一键切换图书状态的路由修改文件 config/routes.rb
Rails.application.routes.draw do ....... * resources :books * namespace :admin do resources :books do collection do post "book_update" end end * end end
5.2 books 数据表增加 book_state字段
终端执行#添加图书状态字段 rails g migration add_book_state_to_book #添加图书库存字段 rails g migration add_book_stock_to_book
配置文件 db/migrate/xxxx一堆数字xxxx_add_book_state_to_book.rb
class AddBookStateToBook < ActiveRecord::Migration[5.1] * def change add_column :books, :book_state, :string * end end
配置文件 db/migrate/xxxx一堆数字xxxx_add_book_stock_to_book.rb
class AddBookStockToBook < ActiveRecord::Migration[5.1] * def change add_column :books, :book_stock, :integer * end end
5.3 Controller 设置图书状态切换方法
修改文件 app/controllers/admin/books_controller.rb* def destroy def book_update @book = Book.find(params[:id]) #接受view层传递的id参数 if @book.book_state == "上架" #图书状态如果为"上架"字符串 @book.update(book_state: "下架") #更新为"下架"字符串状态 flash[:error] = "下架成功" else #图书状态为非"上架"字符串 @book.update(book_state: "上架") #更新为"上架"字符串状态 flash[:error] = "上架成功" end redirect_to admin_books_path end * private * def book_params params.require(:book).permit(:title, :text, :book_stock, :book_state) * end end
5.4 View 层, 配置 book_state 代码
修改文件 app/views/admin/books/index.html.erb<h1>图书馆后台</h1> + <%=flash[:error]%> + <%=flash[:waning]%> + <%=flash[:notice]%> <p> + <%= link_to "新书上架", new_admin_book_path %> </p> <table class="table table-bordered table-hover"> <tr class="text-info"> <th>书名</th> <th>简介</th> + <th>库存</th> + <th>状态</th> <th>操作</th> </tr> <% @books.each do |book| %> <tr class="text-info"> <td><%= book.title %></td> <td><%= book.text %></td> + <td><%= book.book_stock %></td> + <td><%= link_to("#{book.book_state}", book_update_admin_books_path(:id => book.id), method: :post , :class => "btn btn-xs btn-default") %></td>
6、借书单实作
6.1 配置路由
设定借书单、借书、还书的路由。config/routes.rb
* namespace :admin do ..... # 本页代码最下方 resources :borrows #借书单 resources :books do member do post :add_to_borrow #借书 post :return_book #还书 end end
6.2 建立 borrows 与 borrow_items 数据表
终端执行rails g migration create_borrows rails g migration create_borrow_items
配置文件 db/migrate/xxxx一堆数字xxxx_borrow.rb
class CreateBorrows < ActiveRecord::Migration[5.1] * def change * create_table :borrows do |t| t.timestamps * end * end end
配置文件 db/migrate/xxxx一堆数字xxxx_borrow_items.rb
class CreateBorrowItems < ActiveRecord::Migration[5.1] * def change * create_table :borrow_items do |t| t.integer :borrow_id t.integer :book_id t.integer :quantity, default: 1 t.timestamps * end * end end
6.3 建立 borrow 与 borrow_item 的模型
终端执行touch app/models/borrow.rb touch app/models/borrow_item.rb
配置文件 app/models/borrow.rb
class Borrow < ApplicationRecord has_many :borrow_items has_many :books, through: :borrow_items, source: :book def add_book_to_borrow(book) bi = borrow_items.build bi.book = book bi.quantity = 1 bi.save end end
配置文件 app/models/borrow_item.rb
class BorrowItem < ApplicationRecord belongs_to :book belongs_to :borrow end
6.4 Model 层,测试借书动作
终端进入 rails c (后台金手指)rails c book = Book.first Borrow.create borrow = Borrow.first borrow.add_book_to_borrow(book) borrow.borrow_items
6.5 Controller 层,配置文件
终端执行touch app/controllers/borrows_controller.rb
配置文件 app/controllers/borrows_controller.rb
class BorrowsController < ApplicationController end
修改文件 app/controllers/books_controller.rb
class BooksController < ApplicationController ...... * def show * end def add_to_borrow #加入借书单 @book = Book.find(params[:id]) if !current_borrow.books.include?(@book) current_borrow.add_book_to_borrow(@book) @book.book_stock = @book.book_stock - 1 @book.save flash[:notice] = "成功将 #{@book.title} 加入借书单" else flash[:waning] = "你的借书单已有本书" end redirect_to books_path end def return_book #还书 @borrow_item = BorrowItem.find(params[:id]) if @borrow_item.destroy @borrow_item.book.book_stock = @borrow_item.book.book_stock + 1 @borrow_item.book.save redirect_to borrows_path flash[:notice] = "还书成功" else flash[:error] = "还书失败" end end *end
6.5 View 层,配置借书、还书、借书单
修改文件 app/views/common/_navbar.html.erb ,导航栏加入借书单按钮* <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> * <ul class="nav navbar-nav navbar-right"> <li> <%= link_to borrows_path do %> 借书单 <i class="fa fa-shopping-borrow"> </i> ( <%= current_borrow.books.count %> ) <% end %> </li> * <% if !current_user %> * <li><%= link_to("注册", new_user_path) %> </li>
终端执行
mkdir app/views/borrows touch app/views/borrows/index.html.erb
配置文件 app/views/borrows/index.html.erb
<h1>借书单</h1> <table class="table table-bordered table-hover"> <tr class="text-info"> <th>书名</th> <th>简介</th> <th>库存</th> <th>操作</th> </tr> <% current_borrow.borrow_items.each do |borrow_item| %> <tr> <th><%= borrow_item.book.title %></th> <th><%= borrow_item.book.text %></th> <th><%= borrow_item.book.book_stock %></th> <th><%= link_to '还书', return_book_book_path(:id => borrow_item.id), :method => :post, :class => "btn btn-primary btn-lg btn-danger" %></th> </tr> <% end %> </table>
修改文件 app/views/books/index.html.erb ,加入借书按钮
* <td><%= book.book_stock %></td> * <td> * <%= link_to '显示', book_path(book) %> <%if current_user%> <span style="margin-left: 5px;">|</span> <%= link_to '借阅', add_to_borrow_book_path(:id => book.id), :method => :post, :class => "btn btn-primary btn-lg btn-danger" %> <%end%> * </td>
相关文章推荐
- Rails 实战——图书管理系统——基础建设
- Vue 2.x 实战之后台管理系统开发(一)
- 基于jsp+servlet图书管理系统之后台用户信息修改操作
- android图书管理系统+javaweb后台服务器代码
- Node.js 切近实战(五) 之图书管理系统(图书Gallery)
- 基于jsp+servlet图书管理系统之后台用户信息删除操作
- Node.js 切近实战(四) 之图书管理系统(图书查询)
- C链表和文件操作实战--图书管理系统
- rails.图书管理系统——图书“上架”状态一键切换
- 【图书管理系统】--后台实现打印
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发1-准备工作
- Node.js 切近实战(三) 之图书管理系统(图书信息录入)
- php-简单后台图书管理系统-数据库表的创建以及pdo方式数据库的封装工具类01
- 图书管理系统(前台加后台管理)
- Node.js 切近实战(五) 之图书管理系统(图书Gallery)
- Node.js 切近实战(四) 之图书管理系统(图书查询)
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发3-登录模块开发
- Node.js 切近实战(三) 之图书管理系统(图书信息录入)
- Node.js 切近实战(二) 之图书管理系统(登录)
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发4- 后台模板html页面创建