Rails 实战——图书管理系统——基础建设
2018-03-26 09:27
417 查看
目标
搭建 rails 项目的基础注意两个 “+….” 符号中间的代码,是新增代码
1、确认操作环境
进入终端页面ruby -v #=> ruby 2.3.1p112 rails -v #=> Rails 5.1.4
常用终端指令
git status # 查看 git 状态 rake routes # 查看路由
2、建立 Rails 专案
rails new library01
cd library01
git init
git add .
git commit -m "First Commit"
2.1 安装 Mysql 数据库
git checkout -b ch01 # 建立新分支
修改 Gemfile 文件
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.1.4' - # Use sqlite3 as the database for Active Record - gem 'sqlite3' + # Use mysql2 as the database for Active Record + gem 'mysql2'
2.2 修改数据库配置文件
文件 config/database.yml 修改为下面形式development: adapter: mysql2 #数据库类型 database: rails01 #数据库名字(需要修改) username: root #用户名 password: #用户密码 host: localhost #ip地址 production: adapter: mysql2 database: rails01 username: root password: host: localhost
# 启动 Mysql 数据库 mysql.server start # 建立数据库 rake db:create git status git add . git commit -m "install mysql"
3、建立 Welcome 页面
在文件 config/routes.rb 添加 welcome 页面路由Rails.application.routes.draw do root 'welcome#index' # 确定首页路由 end
新建文件
touch app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController def index end end
新建文件夹
mkdir app/views/welcome
新建文件
touch app/views/welcome/index.html.erb
<h1>Hello World</h1>
再开一个终端页面,执行
rails s
打开 http://localhost:3000 页面
![](https://ws4.sinaimg.cn/large/006tKfTcly1fn4j5f7bk0j30dq05s0sv.jpg)
git add . git commit -m "implement welcome#html"
4、布置网站样式
4.1 将 Bootstrap 的 CSS 套件装进专案里面
Gemfile+ gem 'bootstrap-sass' group :development, :test do
修改文件名,终端输入
mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
然后修改 app/assets/stylesheets/application.scss 档案,在最后加入以下两行
/* * ...(一堆注解) *= require_tree . *= require_self */ + @import "bootstrap-sprockets"; + @import "bootstrap";
将变更 commit 进 git 里面
git add .
git commit -m "add bootstrap to project"
4.2 修改 Views 样式
修改文件 app/views/layouts/application.html.erb<head> - <title>Rails05</title> + <title>图书管理系统</title> <body> - <%= yield %> +...... <div class="container-fluid"> <%= render "common/navbar" %> <%= yield %> </div> <%#= render "common/footer" %> +...... </body>
4.3新增 navbar
新增 app/views/common 资料夹mkdir app/views/common
新增 navbar 导航栏
touch app/views/common/_navbar.html.erb
填入 app/views/common/_navbar.html.erb
<nav class="navbar navbar-default" role="navigation"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <a class="navbar-brand" href="/">图书管理系统</a> <!-- href="#"是点击按钮跳转路径,将符号"#"替换为相对网址路径,例如"/"表示首页路径 --> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav navbar-right"> <li><%= link_to("登录", '#') %></li> <!-- 在 rails 中 "link_to" 是 "<a>" 的封装 --> </ul> </div> <!-- /.navbar-collapse --> </div> <!-- /.container-fluid --> </nav>
4.4新增 footer
touch app/views/common/_footer.html.erb
填入app/views/common/_footer.html.erb
<footer class="container-fluid navbar-fixed-bottom" style="margin-top: 100px;"> <p class="text-center">图书管理系统 <br>Planck1043 </p> </footer>
git add . git commit -m "update view style"
参考资料:
CSS五种方式实现Footer置底
navbar固定 和 footer置底的方法
![](https://ws1.sinaimg.cn/large/006tKfTcly1fn4liih4e0j30o80gfwfa.jpg)
5、安装 flash 消息提示功能
5.1 将 Boostrap 的 js 提示套件 bootstrap/alert “挂”进专案里面
在requre_tree上加入一行
//= require bootstrap/alert
app/assets/javascripts/application.js
... (一堆注解) //= require jquery_ujs //= require turbolinks +//= require bootstrap/alert //= require_tree .
5.2 新增 app/views/common/_flashes.html.erb
touch app/views/common/_flashes.html.erb
填入 app/views/common/_flashes.html.erb
<% if flash.any? %> <% user_facing_flashes.each do |key, value| %> <div class="alert alert-dismissable alert-<%= flash_class(key) %>"> <button class="close" data-dismiss="alert">×</button> <%= value %> </div> <% end %> <% end %>
5.3 加入 app/helpers/flashes_helper.rb
touch app/helpers/flashes_helper.rb
填入以下内容:
app/helpers/flashes_helper.rb
module FlashesHelper FLASH_CLASSES = { alert: "danger", notice: "success", warning: "warning"}.freeze def flash_class(key) FLASH_CLASSES.fetch key.to_sym, key end def user_facing_flashes flash.to_hash.slice "alert", "notice","warning" end end
5.4 在 application.html.erb
内加入 flash 这个 partial
在 <%= yield %>前加入
<%= render "common/flashes" %>
app/views/layouts/application.html.erb
+ <%= render "common/flashes" %> <%= yield %>
5.5 git 存档
git add . git commit -m "add bootstrap flash function"
5.6 测试 flash helper 的功能(可以略过)
加入 flash[:notice] = “早安!你好!”。你应该可以看到系统跳出“绿色”提示窗。app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController def index flash[:notice] = "早安!你好!" end end
![](https://ws1.sinaimg.cn/large/006tKfTcly1fn4mzj0nv8j30o10e0755.jpg)
6、安装 Sorcery(轻量级会员系统)
devise 和 sorcery 都是会员系统。devise是重量级的,sorcery是轻量级的。
安装gem
Gemfile+ gem 'sorcery' group :development, :test do
终端执行
$ bundle install
重启
$ rails s
初始化安装
$ rails g sorcery:install
如何安装sorcery提供的子功能(可以忽略)
比如下面的重置密码功能,可以参考config/initializers/sorcery.rb文件$ rails generate sorcery:install reset_password --only-submodules
配置参数文件
配置文件/config/initializers/sorcery.rb,这些地方需要配置,将激活功能删除,减少配置的复杂度user.user_activation_mailer = nil user.activation_mailer_disabled = true user.prevent_non_active_users_to_login = false
Sorcery具体使用
sorcery只有针对密码的加密功能,但是没有针对密码的校验和密码一致性的校验。执行上面的模块建立方式:$ rails g sorcery:install remember_me reset_password user_activation --only-submodules
config/initializers/sorcery.rb参考如上的配置方式。
修改文件
config/routes.rb
Rails.application.routes.draw do root 'welcome#index' resources :users resources :sessions end
终端执行
rake db:migrate
配置文件
model/user.rb
class User < ApplicationRecord authenticates_with_sorcery! attr_accessor :password, :password_confirmation validates_presence_of :email, message: "邮箱不能为空" validates :email, uniqueness: true validates_presence_of :password, message: "密码不能为空", if: :need_validate_password validates_presence_of :password_confirmation, message: "密码确认不能为空", if: :need_validate_password validates_confirmation_of :password, message: "密码不一致", if: :need_validate_password validates_length_of :password, message: "密码最短6位", minimum: 6, if: :need_validate_password private def need_validate_password self.new_record? || (!self.password.nil? or !self.password_confirmation.nil?) end end
配置文件 app/controllers/users_controller.rb
class UsersController < ApplicationController def new @user = User.new end #用户注册 def create @user = User.new(params.require(:user) .permit(:email, :password, :password_confirmation)) if @user.save flash[:notice] = '注册成功,请登录' redirect_to new_session_path else render action: :new end end #用户密码修改 def change_password if current_user.valid_password?(params[:old_password]) current_user.password_confirmation = params[:password_confirmation] if current_user.change_password!(params[:password]) render json: {status: 'ok', msg: '密码修改成功'} else render json: {status: 'error', msg: current_user.errors.messages.values.flatten} end else render json: {status: 'error', msg: '旧密码不正确'} end end #用户发送忘记密码邮件,这里需要对邮件进行配置 def send_forget_password_email @user = User.find_by(email: params[:email]) if @user @user.deliver_reset_password_instructions! render json: {status: 'ok', msg: "重置密码的链接已发送到上面的邮箱"} else render json: {status: 'error', msg: '指定邮箱不存在'} end end #密码重置 def reset_password @user = User.load_from_reset_password_token(params[:token]) if @user @user.password_confirmation = params[:password_confirmation] if @user.change_password!(params[:password]) render json: {status: 'ok', msg: '密码修改成功'} else render json: {status: 'error', msg: @user.errors.messages.values.flatten} end else render json: {status: 'error', msg: 'token不正确或者已过期'} end end end
配置文件 app/views/users/new.html.erb
<h1>用户注册</h1> <div> <% unless @user.errors.empty? %> <ul> <% @user.errors.messages.values.flatten.each do |error| %> <li><%= error %></li> <% end -%> </ul> <% end -%> </div> <%= form_for :user, url: users_path, method: :post, html: { class: 'form-horizontal', id: "user_form"} do |f| %> <div class="form-group"> <div class="col-lg-12">邮箱 *</div> <div class="col-lg-12"> <%= f.text_field :email, class: "form-control" %> </div> </div> <div class="form-group"> <div class="col-lg-12">密码 *</div> <div class="col-lg-12"> <%= f.password_field :password, class: "form-control" %> </div> </div> <div class="form-group"> <div class="col-lg-12">密码确认 *</div> <div class="col-lg-12"> <%= f.password_field :password_confirmation, class: "form-control" %> </div> </div> <div class="form-group"> <div class="col-lg-12"> <div class="text-center"> <a href="<%= new_session_path %>">登录</a> </div> </div> </div> <div class="form-group"> <div class="col-lg-12"> <input type="submit" name="create_user_submit" value="创建账户" class="col-xs-12 btn btn-primary"> </div> </div> <% end %>
配置文件 app/controllers/sessions_controller.rb
class SessionsController < ApplicationController before_action :auth_user, except: [:destroy] def new end def create #login是sorcery的登录方法 if user = login(params[:email], params[:password]) flash[:notice] = '登陆成功' redirect_to root_path else flash[:notice] = "邮箱或者密码错误" redirect_to new_session_path end end def destroy #logout是sorcery的退出方法 logout flash[:notice] = "退出登陆" redirect_to root_path end private def auth_user #logged_in?是sorcery的判断登录方法 if logged_in? redirect_to root_path end end end
配置文件 app/views/sessions/new.html.erb
<h1>用户登录</h1> <%= form_tag sessions_path, method: :post, class: "form-horizontal" do %> <div class="form-group"> <div class="col-lg-12">邮箱</div> <div class="col-lg-12"> <%= text_field_tag :email, nil, class: "form-control" %> </div> </div> <div class="form-group"> <div class="col-lg-12">密码</div> <div class="col-lg-12"> <%= password_field_tag :password, nil, class: "form-control" %> </div> </div> <div class="form-group"> <div class="col-lg-12"> <div class="text-center"> <a href="<%= new_user_path %>">注册</a> </div> </div> </div> <div class="form-group"> <div class="col-lg-12"> <input type="submit" name="sign_submit" value="登陆" class="col-xs-12 btn btn-primary"> </div> </div> <% end %>
参考资料:
- gem sorcery的使用
- 参考博客原话:我的github上一个项目用的这个gem,懒得研究的同学直接去我我的github上面copy代码吧…
- https://github.com/mypassword99/my-shop
- Sorcery具体使用
![](https://ws2.sinaimg.cn/large/006tNbRwly1fnbdmm581tj30o90hz75n.jpg)
![](https://ws2.sinaimg.cn/large/006tNbRwly1fnbdmc9ceyj30o90hz0u2.jpg)
相关文章推荐
- Rails 实战——图书管理系统——图书后台
- [零基础学JAVA]Java SE实战开发-37.MIS信息管理系统实战开发[JDBC](3) 推荐
- C语言基础上的图书管理系统
- Rails Web应用开发实战-学生选课系统基础版(二)
- 基于C语言的基础图书管理系统
- 黑马程序员——java基础项目:交通灯管理系统项目实战
- C链表和文件操作实战--图书管理系统
- 实战CRM系统项目:4.基础配置-区域管理
- Node.js 切近实战(四) 之图书管理系统(图书查询)
- Node.js 切近实战(三) 之图书管理系统(图书信息录入)
- rails.图书管理系统——图书“上架”状态一键切换
- Node.js 切近实战(五) 之图书管理系统(图书Gallery)
- Java基础(十六)——项目实战——交通灯管理系统
- Node.js 切近实战(五) 之图书管理系统(图书Gallery)
- Node.js 切近实战(四) 之图书管理系统(图书查询)
- [零基础学JAVA]Java SE实战开发-37.MIS信息管理系统实战开发[文件保存](1) 推荐
- [零基础学JAVA]Java SE实战开发-37.MIS信息管理系统实战开发[JDBC](1) 推荐
- 浙江交通基础信息应用平台及公路信息管理系统建设项目
- [零基础学JAVA]Java SE实战开发-37.MIS信息管理系统实战开发[文件保存](2) 推荐
- Oracle之实战(图书管理系统)