rails 5 功能新增及改变
1、ApplicationRecord
在Rails4中所有的模型都继承自ActiveRecord::Base,不过在Rails5中新引进了一个叫ApplicationRecord的类,存放在: app/models/application_record.rb中,所有Rails5应用都会有这个类, 它的内容非常简单:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
就是一个继承ActiveRecord::Base的抽象类,作用就是为整个应用程序模型提供一个自己的基类
module MyModule
end
# Rails4.x中扩展模型的方式
ActiveRecord::Base.send :include, MyModule
# Rails5
class ApplicationRecord < ActiveRecord::Base
include MyModule
self.abstract_class = true
end
2、OR语法支持(查询语句的组合查询),Rails5中提供了对两个AR Relation对象的OR方法:
> Article.where(user_id: 1).or(Article.where(user_id: 2))
=> Article Load (2.5ms) SELECT `articles`.* FROM `articles` WHERE (`articles`.`user_id` = 1 OR `articles`.`user_id` = 2)
需要注意的是如果你在第一个Relation中是用了:limit distinct offset 这三个方法的话,那么就必须在后面的Relation中也使用相同的方法,否则的话就会报错
> Article.where(user_id: 1).limit(1).or(Article.where(user_id: 2))
#=>ArgumentError: Relation passed to #or must be structurally compatible. Incompatible values: [:limit]
最好是在结尾使用:
Article.where(user_id: 1).or(Article.where(user_id: 2)).limit(1)
3、ActiveRecord::Relation#cache_key
Rails中使用缓存是很常见的行为,通常我们要缓存一组查询出来的记录,需要手动的设置缓存的key
no_nick_name_users = User.where(nick_name: nil)
cache_key = [User.name, 'no_nick_name_users', no_nick_name_users.maximum(:updated_at).to_i]
Rails.cache.fetch(cache_key) do
no_nick_name_users.to_a
end
Rails5中提供了ActiveRecord::Relation#cache_key
no_nick_name_users = User.where(nick_name: nil)
Rails.cache.fetch(no_nick_name_users.cache_key) do
no_nick_name_users.to_a
end
puts no_nick_name_users.cache_key
#=> "users/query-dae9b6f1d9babd4a9ec4c532614c29eb-1-20160703095605000000"
上面最后一行,Rails5提供的cache_key和我们自己设置的很相似,分别有5个组成部分分别是:
users : 表名
query : 常值
dae9b6f1d9babd4a9ec4c532614c29eb : 缓存SQL的MD5码
1 : 结果集数量
20160703095605000000 : 结果集最大的updated_at的时间戳
4、AR Relation调用update会触发callbacks和validates
在Rails4中的AR Relation 提供了两个更新记录的方法update_all和update其中:
update_all 通过一条SQL语句更新多条记录,不能触发callback和validate
update 通过N条SQL语句,更新N条记录,其中N取决于其第一个ID参数的个数。
通过上面的方法定义,可以看出,如果你不知道ID的情况下,想更新一组记录并且触发它们各自的callback和validate,在Rails4中是做不到的。
那么在Rails5中修改了AR Relation#update的实现:
def update(id = :all, attributes)
if id.is_a?(Array)
id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) }
elsif id == :all
to_a.each { |record| record.update(attributes) }
else
object = find(id)
object.update(attributes)
object
end
end
也就是亦可以通过下面的方法更新记录:
2.3.0 :007 > User.where(nick_name: 'Falm').update(nick_name: 'falm')
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`nick_name` = 'Falm'
(0.1ms) BEGIN
SQL (0.3ms) UPDATE `users` SET `nick_name` = 'falm', `updated_at` = '2016-07-03 05:00:18' WHERE `users`.`id` = 1
(2.0ms) COMMIT
(0.1ms) BEGIN
SQL (0.2ms) UPDATE `users` SET `nick_name` = 'falm', `updated_at` = '2016-07-03 05:00:18' WHERE `users`.`id` = 2
(0.3ms) COMMIT
(0.1ms) BEGIN
SQL (0.2ms) UPDATE `users` SET `nick_name` = 'falm', `updated_at` = '2016-07-03 05:00:18' WHERE `users`.`id` = 3
(0.2ms) COMMIT
(0.1ms) BEGIN
SQL (0.2ms) UPDATE `users` SET `nick_name` = 'falm', `updated_at` = '2016-07-03 05:00:18' WHERE `users`.`id` = 4
(0.2ms) COMMIT
更新操作被按ID分解成多个update语句,并且其中每一个都会执行callback和validates, 要注意的是如果你要更新的记录不必要触发callback或validates,那么因为性能原因最好使用update_all方法。
更新记录时,不更新updated_at/updated_on
Rails4.x中,更新记录是,AR都会连带更新,记录上的updated_at或updated_on字段。
在Rails5中,为ActiveRecord::Base#save方法提供了一个选项,touch: boolean,默认情况下是true,如果设置成false的话,更新记录是就不会更新updated_at字段了。
2.3.0 :027 > user = User.first
User Load (0.3ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
=> #<User id: 1, phone: "13303300333", email: nil, sign_in_count: 0, name: "Jason", nick_name: "falm", encrypted_password: nil, created_at: "2016-07-03 05:00:14", updated_at: "2016-07-03 05:00:18">
2.3.0 :028 > user.phone = '15088833388'
=> "15088833388"
2.3.0 :029 > user.save(touch: false)
(0.2ms) BEGIN
SQL (0.3ms) UPDATE `users` SET `phone` = '15088833388' WHERE `users`.`id` = 1
(0.4ms) COMMIT
=> true
2.3.0 :030 > user.updated_at
=> Sun, 03 Jul 2016 05:00:18 UTC +00:00
5、忽略字段
Rails5中新增了 ActiveRecord::Base.ignored_columns 方法,用于忽略数据表中不需要的字段(model中定义忽略的字段)。
class User < ApplicationRecord
self.ignored_columns = ['sign_in_count']
end
这样在模型中就不会有这个字段了
2.3.0 :033 > User.first
User Load (0.2ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
=> #<User id: 1, phone: "15088833388", email: nil, name: "Jason", nick_name: "falm", encrypted_password: nil, created_at: "2016-07-03 05:00:14", updated_at: "2016-07-03 05:00:18">
6、Belongs_to关联,默认必填
在Rails5中AR中的belongs_to 关联,默认情况下是不能为空的:
class User < ApplicationRecord
end
class Article < ApplicationRecord
belongs_to :user
end
> Article.create(title: 'without user').errors.full_messages.to_sentence
(0.2ms) BEGIN
(0.1ms) ROLLBACK
=> "User must exist"
Article属于User,但是如果没有在创建时指定user的话,就无法通过AR的validates,如果你想去除这个默认选项的话,可以通过下面的方式:
class Article < ApplicationRecord
belongs_to :user, optional: true, #指定可选
end
也可以在application.rb中全局设置这个特性为可选的。
Rails.application.config.active_record.belongs_to_required_by_default = false
7、新的 after_{create,update,delete}_commit 回调
在Rails4中,我们可以在模型中设置事务执行后的回调方法,
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# phone :string(255) not null
# email :string(255)
# sign_in_count :integer default(0)
# name :string(255) not null
# nick_name :string(255)
# encrypted_password :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class User < ApplicationRecord
after_commit :send_message, on: :create
after_commit :send_message, on: :update
after_commit :send_message, on: :destroy
private
def send_message
do_someting
end
end
以上就是分别在 创建,更新,和删除事务执行后,被调用的回调方法
那么在Rails5中给它们分别提供的单独的别名方法:
class User < ApplicationRecord
after_create_commit :send_message
after_update_commit :send_message
after_destroy_commit :send_message
private
def send_message
do_someting
end
end
8、rails4中执行数据迁移使用rake,rails5中为了不来回切换而统一使用rails即可:
rails 4:rake db:migrate
rails 5:rails db:migrate
9、支持在migration中添加comments
在大多数的项目中,快速变化的业务模型是很常见的事情,随之而来的就是数据模型的频繁变化,在这种场景下,我们通常会使用 migration_comments + annotate_models 这两个gem 去为模型添加注释信息,以便能够更好的解释模型的由来和用途。现在Rails5原生支持了 migration_comments的功能:
#encoding: utf-8
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, comment: '用户表' do |t|
t.string :phone, null: false, comment: '手机号'
t.string :email, comment: '邮箱'
t.integer :sign_in_count, default: 0, comment: '登录次数'
t.string :name, null: false, comment: '用户名'
t.string :nick_name, comment: '昵称'
t.string :encrypted_password, comment: '加密密码'
t.timestamps
end
end
end
运行迁移:
$> rails db:migrate
== 20160703025729 CreateUsers: migrating ======================================
-- create_table(:users, {:comment=>"用户表"})
-> 0.0178s
== 20160703025729 CreateUsers: migrated (0.0179s) =============================
在mysql数据库中也可以查看到注释:
mysql> show full columns from users;
+--------------------+--------------+-----------------+--------+-------+-----------+----------------+---------------------------------+-----------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
|--------------------+--------------+-----------------+--------+-------+-----------+----------------+---------------------------------+-----------|
| id | int(11) | <null> | NO | PRI | <null> | auto_increment | select,insert,update,references | |
| phone | varchar(255) | utf8_general_ci | NO | | <null> | | select,insert,update,references | 手机号 |
| email | varchar(255) | utf8_general_ci | YES | | <null> | | select,insert,update,references | 邮箱 |
| sign_in_count | int(11) | <null> | YES | | 0 | | select,insert,update,references | 登录次数 |
| name | varchar(255) | utf8_general_ci | NO | | <null> | | select,insert,update,references | 用户名 |
| nick_name | varchar(255) | utf8_general_ci | YES | | <null> | | select,insert,update,references | 昵称 |
| encrypted_password | varchar(255) | utf8_general_ci | YES | | <null> | | select,insert,update,references | 加密密码 |
| created_at | datetime | <null> | NO | | <null> | | select,insert,update,references | |
| updated_at | datetime | <null> | NO | | <null> | | select,insert,update,references | |
+--------------------+--------------+-----------------+--------+-------+-----------+-----------
rails 5 功能新增及改变的更多相关文章
- Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币
什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...
- java在线聊天项目0.4版本 制作服务端接收连接,客户端连接功能 新增客户端窗口打开时光标指向下边文本域功能,使用WindowListener监听WindowAdapter
建一个服务端类ChatServer,用于设置端口接收连接 package com.swift; import java.io.IOException; import java.net.ServerSo ...
- RandomAccessFile()实现用户注册功能, 新增,查询,更新
package seday03.raf;import java.io.IOException;import java.io.RandomAccessFile;import java.util.Arra ...
- Windows Server 2016-DNS 新增或改进功能
本章节补充介绍在 Windows Server 2016 中域名系统 (DNS) 服务器新增或已更改的功能相关信息,具体内容如下: 功能 新增或改进 描述 DNS 策略 新增 您可以配置 DNS 策略 ...
- Excelize 2.5.0 正式发布,这些新增功能值得关注
Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准.可以使用它来读取.写入由 Microsoft Exc ...
- SCVMM之Windows Server2012 R2新功能
在Windows Server 2012 R2中可以通过使用共享的虚拟硬盘VHDX文件的方法来模拟IP SAN,来为虚拟机创建群集提供共享存储.这样为虚拟机创建群集时就不用再像以前一样通过使用软件模拟 ...
- Rails 建立一个资源
在blog 应用程序中.你可以通过脚手架(scaffolded)开始建立一个资源. 这将是单一的blog 提交.请输入以下命令 $ rails generate scaffold Post name: ...
- 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...
- iOS 10 都有什么改变?
iOS 10 都有什么改变? 看这一个贴就够了 最全面的试用 苹果在 WWDC 2016 发布会上正式发布了 iOS 10 操作系统,iOS 与 macOS.tvOS 和 watchOS 构建了苹果四 ...
随机推荐
- 程序员修神之路--kubernetes是微服务发展的必然产物
菜菜哥,我昨天又请假出去面试了 战况如何呀? 多数面试题回答的还行,但是最后让我介绍微服务和kubernetes的时候,挂了 话说微服务和kubernetes内容确实挺多的 那你给我大体介绍一下呗 可 ...
- 并行模式之Master-Worker模式
并行模式之Master-Worker模式 一).Master-Worker模式 作用: 将一个大任务分解成若干个小任务,分发给多个子线程执行. 注: 将大任务分解成小任务,小任务的实现逻辑要相同. 二 ...
- 启动elasticsearch
- name: source env shell: source /etc/profile - name: make elastic permission shell: ...
- 串烧 JavaCAS相关知识
JMM与问题引入 为啥先说JMM,因为CAS的实现类中维护的变量都被volatile修饰, 这个volatile 是遵循JMM规范(不是百分百遵循,下文会说)实现的保证多线程并发访问某个变量实现线程安 ...
- C# - SPC(Statistical Process Control)系统 - 6西格玛数据决策和Chart模块的开发与实现
Statistical Process Control 简介 统计过程控制(Statistical Process Control)是一种借助数理统计方法的过程控制工具.它对生产过程进行分析评价,根据 ...
- MySQL常用的查询语句回顾
让你快速复习语句的笔记宝典. create table users( username varchar(20) primary key, userpwd varchar(20) ) alt ...
- 使用python脚本执行地理处理工具
桌面ArcGIS包含800多种可在Python脚本中运行的地理处理工具. 通过Python脚本来运行地理处理工具,可以处理复杂的工作和执行批处理任务. 案例一:使用脚本执行地理处理工具(以裁剪为例) ...
- Caffe 图像分类
本文主要描述如何使用 CAFFE 进行图像分类. 开发环境要求:windows 10 64位.Visual Studio 2017..NET framework 4.6.1 分类 在一个项 ...
- 英语口语考试资料Volunteers
Being a volunteer is great! There are lots of volunteers around us now. And they don’t do it ...
- 大白话OSI七层协议
目录 一.物理层 二.数据链路层 2.1 以太网协议 2.2 Mac地址 2.3 广播地址 三.网络层 3.1 IP协议详解 3.1.1 IP地址的两部分 3.2 子网掩码详解 3.3 IP数据包详解 ...