#Ruby On Rails

0x00 前言

Rails 6.0 发布已经有一段时间了,之前没有什么项目可以练手,最近总算遇到可以使用Rails 6开发的场景了。Rails 6中新增了一些功能和特性,有一些内容官方文档里并没有写的很具体,所以在摸索的过程中也遇到了一些坑点。这里以一个新工程从头到尾的构建,来简单记录在Rails6中使用jQuery和Bootstrap的过程。希望能够给新来的同学做个参考。

编程和码字的水平有限,如有错漏敬请指教,也请多包涵!下面就开始吧。

0x01 环境准备

  • 操作系统: Debian 10 ( 4.19.0-8-amd64 )
  • Ruby版本: ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
  • Rails版本: Rails 6.0.2.1
1
2
3
4
5
6
7
test@debian:~$uname -a
Linux debian 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64 GNU/Linux
test@debian:~$ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
test@debian:~$rails -v
Rails 6.0.2.1

0x02 创建项目

这里新建一个项目“TestApp”,并在其中建立控制器“Test”和测试方法“test”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
test@debian:~$rails new TestApp
create
create README.md
create Rakefile
create .ruby-version
create config.ru
create .gitignore
create Gemfile
...
├─ [email protected]
├─ [email protected]
└─ [email protected]
Done in 59.74s.
Webpacker successfully installed 🎉 🍰
test@debian:~/TestApp$rails g controller Test test --no-stylesheets
Running via Spring preloader in process 22413
create app/controllers/test_controller.rb
route get 'test/test'
invoke erb
create app/views/test
create app/views/test/test.html.erb
invoke test_unit
create test/controllers/test_controller_test.rb
invoke helper
create app/helpers/test_helper.rb
invoke test_unit
invoke assets
invoke scss
test@debian:~$

创建好之后,修改test页面,添加一个表单和按钮,用于稍后测试Bootstrap。(在执行创建控制器和方法的命令后,Rails已经为我们自动添加了到Test控制器test方法的路由,所以不需要我们再新增路由。)

app/views/test/test.html.erb 代码:

1
2
3
4
5
6
7
<h1>Test#test</h1>
<p>Find me in app/views/test/test.html.erb</p>

<form>
<input id="test" type="text"/>
<button id="test_btn">点我</button>
</form>

启动Rails服务,访问http://localhost:3000/test/test:

1
2
3
4
5
6
7
8
9
10
11
test@debian:~/TestApp$rails s
=> Booting Puma
=> Rails 6.0.2.1 application starting in development
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.1 (ruby 2.6.5-p114), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop

此时应用已经创建成功。

0x03 添加jQuery和Bootstrap库

这里采用yarn作为Javascript包管理器。在TestApp目录中运行bin/yarn,如果出现以下内容,说明yarn没有安装:

1
2
3
test@debian:~/TestApp$bin/yarn
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install

安装方法在这里, 以当前使用的Debian 10为例,安装的方法是:

1
2
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

安装好yarn之后,就可以用yarn添加jQuery包和Bootstrap包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
test@debian:~/TestApp$yarn add jquery 
yarn add v1.21.1
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > [email protected]" has unmet peer dependency "webpack@^4.0.0".
[4/4] Building fresh packages...

success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ [email protected]
info All dependencies
└─ [email protected]
Done in 9.98s.
test@debian:~/TestApp$yarn add bootstrap
yarn add v1.21.1
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > [email protected]" has unmet peer dependency "webpack@^4.0.0".
warning " > [email protected]" has unmet peer dependency "popper.js@^1.16.0".
[4/4] Building fresh packages...

success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ [email protected]
info All dependencies
└─ [email protected]
Done in 13.33s.

由于Bootstrap还需要基于popper.js,不装的话会报依赖错误,所以安装一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
test@debian:~/TestApp$yarn add popper.js
yarn add v1.21.1
[1/4] Resolving packages...
warning [email protected]: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > [email protected]" has unmet peer dependency "webpack@^4.0.0".
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ [email protected]
info All dependencies
└─ [email protected]
Done in 11.78s.

安装的执行结果:

因为众所周知的原因,网速慢的同学就尴尬了,这里可能要等很久,所以你需要选一个科学一点的方式。

此时查看TestApp/node_modules目录,所需的前端库已经添加好了:

1
2
3
4
5
6
7
test@debian:~/TestApp$ls node_modules/jquery/
AUTHORS.txt bower.json dist external LICENSE.txt package.json README.md src
test@debian:~/TestApp$ls node_modules/bootstrap/
dist js LICENSE package.json README.md scss
test@debian:~/TestApp$ls node_modules/popper.js/
dist index.d.ts index.js.flow package.json README.md src
test@debian:~/TestApp$

0x04 使用Bootstrap

跟Rails5有所不同的是,Rails6采用webpack打包的方式,把需要打包的资源统一放在一个文件里(Rails6之前是采用Gemfile的方式引入第三方库,再通过Asset Pipeline汇聚)。

于是在安装好所需的前端库之后,就需要在app/javascript/packs/application.js中先引用它:

以Bootstrap为例,在其中添加import 'bootstrap'引入语句:

与此同时还需要在application.scss中引入Bootstrap的CSS样式表:

app/assets/stylesheets/application.scss文件中添加@import "bootstrap/dist/css/bootstrap";


2020/05/28 Patch

纠个错,如果想要通过@import "bootstrap/dist/css/bootstrap";的方式引用bootstrap相关的CSS,需要把app/assets/stylesheets/application.css文件重命名为app/assets/stylesheets/application.scss
如果直接使用app/assets/stylesheets/application.css的话,那么采用如下方式来引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
* File: app/assets/stylesheets/application.css
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
* vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require bootstrap/dist/css/bootstrap
*= require_tree .
*= require_self
*/

Ending Patch


接着继续修改app/views/test/test.html.erb文件中的代码,添加相应的CSS类来测试Bootstrap是否已经引入成功:

1
2
3
4
5
6
7
8
9
<h1>Test#test</h1>
<p>Find me in app/views/test/test.html.erb</p>

<form>
<div class="form-group">
<input id="test" type="text" class="form-control"/>
<button id="test_btn" class="btn btn-success">点我</button>
</div>
</form>

启动应用,再次访问测试页面:

虽然界面有点丑,但是从渲染效果来看,Bootstrap已经成功引入了。

0x05 使用jQuery

继续修改app/javascript/packs/application.js,添加用于测试jQuery的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")


// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

import 'bootstrap'

$(document).on('turbolinks:load', function(){
$("#test_btn").click(function(){
alert($("#test").val());
});
});

保存并运行,刷新https://localhost:3000/test/test页面,发现添加的代码无法执行,控制台中有报错:

1
2
ReferenceError: $ is not defined 
application.js:21

这是因为jQuery库也需要引入一下,但是引入的方式有些不同,并不是在页面中直接引入,而是需要在config/webpack/environment.js中添加以下引入代码:

1
2
3
4
5
6
var webpack = require('webpack');
environment.plugins.append( 'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
})
)

通过声明一个全局的导出,就可以在全局的JS代码文件中使用”$”符号了。

刷新并再次访问,代码能够运行,控制台也没有再报错,说明jQuery已经成功集成:

另一种方法

还有一种方法是通过在JS文件按中使用import $ from 'jquery'来使”$”符生效,但是这样比较繁琐,需要在每个JS文件中出现,所以不再介绍了,当然,也提供一下详细的代码参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")


// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

import 'bootstrap'
import $ from 'jquery' // 在每个JS文件中加上这一行,也可以替代声明全局变量。

$(document).on('turbolinks:load', function(){
$("#test_btn").click(function(){
alert($("#test").val());
});
});

0x06 总结

在网上主要参考了这篇文章。Rails 6中的变化还是挺大的,不知道webpack会不会真的成为Rails的未来,感觉之前使用coffee script来写JS的同学不是很多,但是我倒是已经非常习惯于使用它来开发前端功能了。

但是想必Rails的先驱们有着他们更成熟的考虑吧,那就一起继续探索好了。

找Rails靠谱的编辑器是不是找了好久了?别找了,就用Simditor吧。
要如何在Rails中完美集成这样一个简洁大气又好用的编辑器呢?我们都知道,在高版本的Rails中使用CoffeeScript已经成为了一种习惯。所以本文将以CoffeeScript作为粘合剂来演示如何集成Simditor编辑器到Rails应用中,同时采用Rails原生的ActiveStorage作为上传支撑。

事先声明下我的环境配置:
Ruby: ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
Rails: Rails 5.2.2

1. 准备工作

首先我们新建一个Rails项目,在命令行中,运行rails new Demo,待工程创建好以后我们进入Demo目录,新建一个脚手架。这里我们就以Article作为脚手架的名字,运行rails g scaffold Article title:string content:text

创建好之后,运行rails db:migrate,迁移数据库

此时,将simeditor添加到Gemfile中。修改Gemfile,加入以下内容并执行bundle(simditor需要jquery的支持)。

1
2
gem 'jquery-rails'
gem 'simditor'

并在app/assets/javascripts/application.js中加入simditor的引用,此处需要注意,下面两行代码需要添加在//= require_tree这行代码之前,否则会出错。

1
2
3
//= require jquery
//= require simditor
//= require_tree .

同时需要在app/assets/stylesheets/application.css中加入simditor的样式文件:

1
*= require simditor

启动Rails应用,在浏览器中访问/articles/new,此时的界面如下:

到这里,准备工作就完成了。

2. 修改编辑框,集成Simditor

按照Rails的命名惯例,此处编辑框textarea的ID是article_content,我们的CoffeeScript脚本中,则需用选择器来绑定这个text_area。

修改app/assets/javascripts/article.coffee,加入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(document).on "turbolinks:load", ->
editor = new Simditor(
textarea: $('#article_content')
toolbar: [ 'bold', 'italic', 'underline', 'strikethrough', 'color',
'code', 'blockquote', 'link', 'image', 'ol', 'ul', 'table', 'indent','outdent','alignment']
pasteImage: true,
fileKey: 'file',
upload: {
url: '/images',
params: {"content":"image"},
connectionCount: 3,
leaveConfirm: '有图片正在上传,确定要离开?'
})

再次在浏览器中访问/articles/new,界面变成了这样:

此时Simditor已经集成到了应用中了。

3. 使用ActiveStorage配置上传功能

ActiveStorage是Rails 5.2 以后推出的用于专门管理Web上传内容的组件,和ActiveRecord一样,是一个很方便同时又很强大的Rails Web开发组件。想要集成基于ActiveStorage的上传功能,首先要在我们的应用中安装ActiveStorage:

运行rails active_storage:install然后再运行rails db:migrate:

1
2
3
4
5
6
7
8
9
root@debian:~/Demo# rails active_storage:install
Copied migration 20190327123314_create_active_storage_tables.active_storage.rb from active_storage
root@debian:~/Demo# rails db:migrate
== 20190327123314 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs)
-> 0.0050s
-- create_table(:active_storage_attachments)
-> 0.0027s
== 20190327123314 CreateActiveStorageTables: migrated (0.0086s) ===============

迁移完成以后,我们新建一个Upload控制器,使用rails g controller Upload命令生成它。修改Upload控制器代码,位于app/controllers/upload_controller.rb,添加一个upload方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#app/controllers/upload_controller.rb
class UploadController < ApplicationController

skip_before_action :verify_authenticity_token, :only => [:upload]

def upload

puts "*"*64
puts params

blob = ActiveStorage::Blob.create_after_upload!(
io: params[:image],
filename: params[:image].original_filename,
content_type: params[:image].content_type
)

if blob.save
success = true
msg = 'upload success'
else
success = false
msg = "upload error"
end

render json: { :success=> success, :msg=>msg, :file_path=> rails_blob_path(blob) }

end

end


修改路由配置文件,指定我们的上传路由:

1
2
3
4
5
6
7
#config/routes.rb
Rails.application.routes.draw do
post 'images/upload' => 'upload#upload'
resources :articles
root to: 'articles#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

还要稍微修改一下我们的articles.coffee文件,改一下其中的上传路径和参数,用于Ajax提交图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//app/assets/javascripts/articles.coffee
$(document).on "turbolinks:load", ->
editor = new Simditor(
textarea: $('#article_content')
toolbar: [ 'bold', 'italic', 'underline', 'strikethrough', 'color',
'code', 'blockquote', 'link', 'image', 'ol', 'ul', 'table', 'indent','outdent','alignment']
pasteImage: true,
fileKey: 'file',
upload: {
url: '/images/upload', //<==上传接口
fileKey: 'image', //<=参数名称
params: {"content":"image"},
connectionCount: 3,
leaveConfirm: '有图片正在上传,确定要离开?'
})

至此,已经可以在页面中正常地上传文件了,也可以直接从粘贴板复制文件,Simditor会自动上传文件:

本文涉及到的代码已经上传到Github,仓库链接:https://github.com/Chorder/RailsSimditorActiveStorageDemo

前言

随着技术的发展,近年很多的网站、移动应用程序、微信小程序等等,采用前后端分离、使用JSON API数据传递这种方式来设计和开发。如此,前端程序可以保持独立、并且相对来说比较完整,后端程序逻辑复杂、性能强劲。前端可以有丰富的对数据的展现方式(图表、动画等等),后端也只需要完善相应的对模型的控制,同时输出一份前端所需要的数据,采用Ajax+JSON方式传递,从而让前后端的开发相对而言都更为轻松,在结构合理、技术完备的情况下,工程层面也能实现较大程度的规模上的突破。

Rails作为一种流行的MVC框架,本身在API的开发上已经有了很成熟的配套设施了。Rails的模板支持.json.jbuilder形式的JSON数据渲染,配合jbuilder从模型对象数组直接创建JSON数据,在开发上有着无与伦比的便利。在此之前,如果使用php开发程序,从数组创建JSON,需要先整理好数组,再json_encode(Array)进行输出,很是麻烦。当然身为PHP程序员的你可能要说,PHP也有很强大的API构建框架,可以很方便的构建出健壮的API,是的,我承认有这些框架的存在,只是限于本人的水平和喜好,在PHP开发方面并没有走的那么深远,也就不熟悉其中的一些高级操作了。如果有兴趣,也可以发邮件就这方面进行一些探讨。

近期由于一个项目的需要,需要从已有的Rails应用中开辟出一个新的独立接口,供客户端程序调用,因此学习了一下Rails API的构建方法,也顺便留下此文,作为记录。关于Rails API的构建,我参考了这篇文章 https://blog.csdn.net/li_001/article/details/65937664

以下就是如何使用Rails构建JSON API

我当前采用的环境是 Ruby 2.4.1 + Rails 5.2.0

配置控制器

首先假设我们的应用已经创建好了,并且建立一个Article模型,包含两个字段,title和content,运行迁移并创建种子数据。

此时进入项目根目录,新建一个控制器:

1
rails g controller api/v1/base --no-assets

这个控制器的代码就会位于app/controllers/api/v1/base_controller.rb,我们需要在其中完善一些权限有关的配置。

由于Rails默认的安全属性,以及我们如果之前自定义了一些控制器中的过滤方法,我们需要在该控制器中跳过它,例如我们首先禁用rails自带的CSRF 保护和CSRF token的输出,以及去除掉返回包中的set-cookies头,由于我的应用还使用了devise作为用户认证的模块,所以还要在此禁用掉authenticate_user方法。
完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Api::V1::BaseController < ApplicationController
# disable the CSRF token
protect_from_forgery with: :null_session

# disable cookies (no set-cookies header in response)
before_action :destroy_session

# disable the CSRF token
skip_before_action :verify_authenticity_token

# skip devise user authentication
skip_before_action :authenticate_user!

def destroy_session
request.session_options[:skip] = true
end
end

创建好base控制器以后,我们需要在这个控制器的基础上派生出一些新的控制器,这里我们新建一个articles控制器

1
rails g controller api/v1/articles --no-assets

此时除了会生成控制器代码以外,还会在app/views/api/v1目录下创建articles目录,作为模板存放的目录。

articles控制器的代码位于app/controllers/api/v1/users_controller.rb,内容如下

先在其中定义一个show方法:

1
2
3
4
5
6
class Api::V1::ArticlesController < Api::V1::BaseController
def show
@article = Article.find(params[:id])
end
end

配置路由

接下来我们对路由config/routes.rb进行配置

1
2
3
4
5
namespace :api do
namespace :v1 do
resources :articles
end
end

配置视图

articles控制器的视图代码位于app/views/api/v1/articles/,我们在其中建立show.json.jbuilder文件,内容如下:

1
2
3
json.article do
json.(@article, :id, :title, :content)
end

上面这段代码,是jbuilder建立json的语句代码,至于jbuilder的用法,可以参考这篇文章http://ohcoder.com/blog/2015/04/19/jbuilder/

访问接口

启动Rails程序,访问/api/v1/articles/1.json,即可看到接口输出的JSON数据。

接口通信

除了从接口获取JSON数据以外,我们还需要向接口POST JSON数据,并希望接口实现数据的解析和保存。
首先像往常一样,需要在控制器中创建create方法,用于新建数据:

1
2
3
def create
@host = Host.create(article_params)
end

呵呵,一行代码,是的,就这么简单。
而article_params,则是个私有方法,大概需要这样实现:

1
2
3
def article_params
params.require(:article).permit(:title, :content)
end

在客户端(或网页中)向该接口发送数据,地址是/api/v1/articles

发送的数据类似下面这样:

1
2
3
4
5
6
{
"article":{
"title":"test",
"content":"a test article from client"
}
}

直接发送这条数据可能会出错,因为在请求的时候需要带上json格式描述

1
2
Content-Type: application/json
Accept: application/json

完整的POST请求,参考下:

1
2
3
4
5
6
7
8
9
10
11
12
POST /api/v1/articles HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Accept: application/json

{
"article":{
"title":"test",
"content":"a test article from client"
}
}

简介

Devise是Rails中一个功能强大、逻辑复杂的用于实现站点用户管理和登录的组件。鉴于Ruby之不重复造轮子的精神思想,Devise是值得去深入研究学习一下的。由于Devise本身的复杂性,这里对搭建的过程做一个记录,也借此分享一下基于Devise实现最基本的站点用户管理和登录的过程。

环境准备

需要在机器上安装Ruby和Rails。
本次编程环境:

  • Debian 9(Kernel 4.9.0-6-amd64)
  • ruby-2.4.1
  • Rails 5.2.0

开始

新建项目

首先新建一个Rails项目TestSite,创建Post scaffold,包含title和body两个字段

1
2
rails new TestSite
rails g scaffold Post title:string body:string

安装Devise

接着在Gemfile中添加devise

1
gem 'devise'

在项目中执行bundle,以及执行devise:install

1
2
bundle
rails generate devise:install

由于我们暂时只在本地测试,因此修改config/environments/development.rb文件,在其中加入mailer配置:

1
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

生成模型

指定Devise将要运行在哪个模型上,这里使用user作为模型,那么运行:

1
rails generate devise User

下一步,就是运行迁移:

1
rails db:migrate

控制器过滤

如果希望在应用运行之前校验用户身份,在ApplicationController中加入以下过滤器:

1
before_action :authenticate_user!

指定路由:

1
root to: 'posts#index'

添加注销功能

在Application的首页,加上用户注销的链接:

1
<%= link_to "Logout", destroy_user_session_path, method: "DELETE"  if current_user %>

配置视图

如果想要自定义登陆界面的视图,则运行以下命令:

1
rails g devise:views users

这里后面带模型名称,就会创建在这个模型范围内的视图(建议这样做,便于以后拓展多重用户身份模型)

此时就可以在相应的视图中自定义登录、注册、重置密码等相应的界面了。

配置控制器

生成控制器就和生成视图的流程是类似的,运行:

1
rails generate devise:controllers users

这样控制器就创建好了。

控制器这一段是值得好好说道说道的。
首先观察下控制器,控制器是可以追加功能的,也可以覆盖原来的方法,不过不推荐这样做,因为从目前经验来看devise自带的控制器已经足够健壮了。但是有时候,我们需要在原有的基础上新增一些功能,例如记录登录日志、增加一点自定义认证方式等等。这里简单介绍下如何在控制器中新增功能。
上一步操作,为我们生成了以下控制器:

1
2
3
4
5
6
app/controllers/users/confirmations_controller.rb
app/controllers/users/passwords_controller.rb
app/controllers/users/registrations_controller.rb
app/controllers/users/sessions_controller.rb
app/controllers/users/unlocks_controller.rb
app/controllers/users/omniauth_callbacks_controller.rb

这里以登录为例,如果我们想要改写登录功能,首先我们要在路由中改写我们要复写的控制器路由:

routes.rb中:

1
2
3
4
5
6
7
8
9
10
11
Rails.application.routes.draw do
#devise_for :users
resources :posts
root to: 'posts#index'

devise_for :users, controllers: {
# 这一行定义了有关sessions的控制选项,交由我们即将复写的sessions控制器处理。
sessions: 'users/sessions'
}

end

接着修改app/controllers/users/sessions_controller.rb,这里我们简单实现一个功能,当用户在前台登陆时,在后台的console中输出用户的登录信息。复写create方法:

1
2
3
4
5
6
7
# POST /resource/sign_in
def create
super
puts "="*64
puts resource.email
puts "="*64
end

尝试在前台登录,控制台输出了我们想要的信息:

待续

Windows中搭建Ruby On Rails环境

步骤如下

  1. 安装ruby (我选择的版本是ruby 2.2.3p173)
  2. 安装rails gem
    在这之前建议先把gem的源换成淘宝的源,速度快点。
    1
    2
    3
    4
    5
    6
    7
    8
    gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/
    gem sources -l
    *** CURRENT SOURCES ***

    https://ruby.taobao.org
    # 请确保只有 ruby.taobao.org

    gem install rails

之后:

1
2
gem install rails
gem install bundler
  1. 安装devkit
    下载地址 http://rubyinstaller.org/downloads

如果是win10,选择 DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe 这个版本。

然后运行,并选择解压到c:\devkit

进入c:\devkit目录
运行

ruby dk.rb init

之后修改config.yml

添加下面三行

1
2
3
---
- C:/Ruby22-x64
- C:/Ruby22-x64

注意把路径换成当前ruby的安装路径,-前后各有一个空格不可忽略。
然后运行

ruby dk.rb install

最后进入需要建立工程的目录,使用如下命令新建rails项目

rails new testapp

如果在此过程中报错,则进入testapp中
使用

bundler install

来安装所需要的依赖包。

如果还报错,修改testapp目录中的Gemfile

将第一行的sources源内容改为

source 'https://ruby.taobao.org/'

然后再执行bundler install命令

Debian中搭建Ruby On Rails开发环境

假设你已经安装好ruby了

接下来安装rvm

$ curl -L https://get.rvm.io | bash -s stable

某些情况下,可能需要编译一下rvm的初始化脚本

我的位置是在/etc/profile.d/rvm.sh,所以运行这一句:

$source /etc/profile.d/rvm.sh

接着安装bundler

gem install bundler

然后安装rails

gem install rails

如果这地方出现错误,尝试使用rvm切换ruby的版本:

rvm install 2.0.0
rvm 2.0.0 --default

CentOS中搭建ruby on rails开发环境

1
2
3
4
5
6
curl -L https://get.rvm.io | bash -s stable
source /usr/local/rvm/bin/rvm
rvm install 2.0.0
rvm 2.0.0 --default
gem install bundler
gem install rails

创建项目

1
rails new BootstrapProject

创建模型

1
rails g scaffold xxx --skip-stylesheets

运行迁移

1
rake db:migrate

如果项目和模型都已经建立好了并已经运行了迁移,那么可以省略以上步骤,直接进入下面的流程

在Gemfile中添加bootstrap,这里使用twitter-bootstrap-rails

1
2
3
4
gem 'jquery-rails'
gem 'less-rails'
gem 'therubyracer'
gem 'twitter-bootstrap-rails'

bundle

1
bundle install

安装bootstrap

1
rails g bootstrap:install

在模型上运用bootstrap

1
rails g bootstrap:themed xxx -f

注:xxx可以是任意的模型,例如模型名称是Article,那么这里的语句就是:

1
rails g bootstrap:themed Articles 

还要在application.js中加上引用,否则bootstrap的一些按钮会失效:

1
2
//= require jquery
//= require twitter/bootstrap

Enjoy it~

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×