Rails 枚举
Rails Model中使用枚举有两种方案,一种是rails内置的enum,一种使用enumerize这个gem,不管哪种都能达到相同的目的。
首先介绍第一种:
一. enum
基本使用方法,以一个案列来说明:
给已经存在的 Company 增加一个 size 属性, 属性包括 large, medium, small 三个选项。
从 Rails4.1 开始,可以通过 ActiveRecord::Enum
来快速实现这样的功能:
class Company < ActiveRecord::Base
enum size: [:large, :medium, :small]
end
这样定义之后,rails会为Company添加一些帮助方法:
Company.sizes
# => {"large"=>0, "medium"=>1, "small"=>2} # Scope methods
Company.large
Company.medium
Company.small # Query methods
company.large?
company.medium? # Action methods
company.large!
company.small!
迁移写法:
enum
的实现是基于该字段是一个 integer 类型的。所以添加这个新的字段我们需要下面的 migration:
class AddSizeToCompanies < ActiveRecord::Migration
def change
add_column :companies, :size, :integer, null: false, default: 0
add_index :companies, :size
end
end
赋值操作:
通过上面 Company.sizes 方法,我们看到 Rails 默认是从0开始对应的。所以上面的 migration 中默认值是0。当新建一个Company时,默认 company 的 size 是 large
company = Company.new
company.size # => "large" # 多种赋值操作
company.size = :medium
company.medium? # => true company.size = 2
company.small? # => true company.large = 'large'
company.large? # => true
此外,enum
会自动添加一些验证,如果给 size 属性赋错误的值,Rails会抛出异常:
company.size = 5
# => ArgumentError: 5 is not a valid billing_category
company.size = :bala
# => ArgumentError: 'bala' is not a valid billing_category
在Form下拉菜单中怎么使用呢?
f.input :size, collection: Company.sizes.keys.map {|s| [s.titleize, s]}, prompt: "Select a size"
注意点:
由于存到数据库的仍然是 number,所以如果有别的应用也使用同样的数据库,那么该应用需要知道对应关系。
Rails4.1 及之后的版本中,由于 enum
会自动产生一些方法,所以要特别注意选项的命名问题,尽量用明确的命名。
另外如果你还需要不同的属性,拥有相同的选项,那么你可以考虑这个 gem activerecord-enum-without-methods
同时在 Rails5 中,就可以使用_prefix
和_postfix
选项来避免相应的问题。·
更好的Migration方法:
上面的migration方法对于产品环境已经有数据的情况下,可能会产生问题。
对于Mysql 数据库,新加字段的时候对于已有的记录,mysql 会自动设置 NOT NULL
的已有记录为 default 但是对于 postgreSQL 就会出现下面的错误:
PG::NotNullViolation: ERROR: column “size” contains null values
这时可以先add_column
添加字段,不要加 NOT NULL 的限制,然后更新已有数据,然后再通过change_column_null
来添加 NOT NULL
限制。
二. enumerize
enumerize是一个gem,使用方法和enum大致相似,就不详细说了,细节可参考项目的github地址:
https://github.com/brainspec/enumerize
Rails 枚举的更多相关文章
- rails enum用于存储数据
http://api.rubyonrails.org/classes/ActiveRecord/Enum.html 新的项目中有一个字段是展示类型,可以用下拉框去做,用string存储具体的类型字段. ...
- rails 常用的验证方法 validates (转)
Agile Web Development with Rails 17.4 validation validate 在save的时候激活validate_on_create ...
- usaco training 4.1.2 Fence Rails 题解
Fence Rails题解 Burch, Kolstad, and Schrijvers Farmer John is trying to erect a fence around part of h ...
- HDU 4277 USACO ORZ(暴力+双向枚举)
USACO ORZ Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Swift enum(枚举)使用范例
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- 编写高质量代码:改善Java程序的151个建议(第6章:枚举和注解___建议88~92)
建议88:用枚举实现工厂方法模式更简洁 工厂方法模式(Factory Method Pattern)是" 创建对象的接口,让子类决定实例化哪一个类,并使一个类的实例化延迟到其它子类" ...
- Objective-C枚举的几种定义方式与使用
假设我们需要表示网络连接状态,可以用下列枚举表示: enum CSConnectionState { CSConnectionStateDisconnected, CSConnectionStateC ...
- Help Hanzo (素数筛+区间枚举)
Help Hanzo 题意:求a~b间素数个数(1 ≤ a ≤ b < 231, b - a ≤ 100000). (全题在文末) 题解: a~b枚举必定TLE,普通打表MLE,真是头疼 ...
- 枚举:enum
枚举 所谓枚举就是指定好取值范围,所有内容只能从指定范围取得. 例如,想定义一个color类,他只能有RED,GREEN,BLUE三种植. 使用简单类完成颜色固定取值问题. 1,就是说,一个类只能完成 ...
随机推荐
- 洛谷P2587 [ZJOI2008] 泡泡堂
题目传送门 分析:一道策略游戏题,要求最大期望得分和最小期望得分.首先分析最大,很显然是可以用一种类似于田忌赛马的思维来做,将两队的实力按照从大到小(其实从小到大也可以)排序,然后就按照顺序比较,可能 ...
- Flask实战第54天:cms删除轮播图功能完成
后台逻辑 编辑cms.views.py @bp.route('/dbanner/',methods=['POST']) @login_required def dbanner(): banner_id ...
- [Atcoder Regular Contest 065] Tutorial
Link: ARC065 传送门 C: 最好采取逆序贪心,否则要多考虑好几种情况 (从前往后贪心的话不能无脑选“dreamer”,"er"可能为"erase"/ ...
- 【数论】【快速幂】【扩展欧几里得】【BSGS算法】bzoj2242 [SDOI2011]计算器
说是BSGS……但是跟前面那题的扩展BSGS其实是一样的……因为模数虽然是质数,但是其可能可以整除a!!所以这两者其实是一样的…… 第一二种操作不赘述. #include<cstdio> ...
- (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly Detection&Recommender Systems
这部分内容来源于Andrew NG老师讲解的 machine learning课程,包括异常检测算法以及推荐系统设计.异常检测是一个非监督学习算法,用于发现系统中的异常数据.推荐系统在生活中也是随处可 ...
- Problem E: 十六进制转十进制
#include<stdio.h> int main(void) { ]; int sum,i; while(gets(str)!=NULL) { sum=; ;str[i]!='\0'; ...
- python的高阶函数
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数. 高阶函数 定义:一个函数就可以接收另一函数作为参数,这种函数就称之为高阶函数. map/reduce Python ...
- [Apache手册]Linux环境下配置Apache运行cgi
CGI动态页面 相关模块 相关指令 mod_alias mod_cgi AddHandler Options ScriptAlias CGI(公共网关接口)定义了web服务器与外部内容生成程序之间交互 ...
- uboot中的快捷菜单的制作说明
转:http://blog.chinaunix.net/uid-22030783-id-366971.html 在uboot中加入快捷操作菜单的方法非常简单,在论坛发布的uboot201003V1.1 ...
- 普通项目转换成maven项目
参看文档:http://czj4451.iteye.com/blog/1983889 maven仓库:http://mvnrepository.com/ 基本步骤如下: Configue--& ...