您的位置:首页 > 大数据 > 人工智能

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 页面



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置底的方法



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




6、安装 Sorcery(轻量级会员系统)

devisesorcery 都是会员系统。

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具体使用



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: