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 枚举的更多相关文章

  1. rails enum用于存储数据

    http://api.rubyonrails.org/classes/ActiveRecord/Enum.html 新的项目中有一个字段是展示类型,可以用下拉框去做,用string存储具体的类型字段. ...

  2. rails 常用的验证方法 validates (转)

    Agile Web Development with Rails 17.4 validation validate              在save的时候激活validate_on_create  ...

  3. 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 ...

  4. HDU 4277 USACO ORZ(暴力+双向枚举)

    USACO ORZ Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. Swift enum(枚举)使用范例

    //: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...

  6. 编写高质量代码:改善Java程序的151个建议(第6章:枚举和注解___建议88~92)

    建议88:用枚举实现工厂方法模式更简洁 工厂方法模式(Factory Method Pattern)是" 创建对象的接口,让子类决定实例化哪一个类,并使一个类的实例化延迟到其它子类" ...

  7. Objective-C枚举的几种定义方式与使用

    假设我们需要表示网络连接状态,可以用下列枚举表示: enum CSConnectionState { CSConnectionStateDisconnected, CSConnectionStateC ...

  8. Help Hanzo (素数筛+区间枚举)

    Help Hanzo 题意:求a~b间素数个数(1 ≤ a ≤ b < 231, b - a ≤ 100000).     (全题在文末) 题解: a~b枚举必定TLE,普通打表MLE,真是头疼 ...

  9. 枚举:enum

    枚举 所谓枚举就是指定好取值范围,所有内容只能从指定范围取得. 例如,想定义一个color类,他只能有RED,GREEN,BLUE三种植. 使用简单类完成颜色固定取值问题. 1,就是说,一个类只能完成 ...

随机推荐

  1. Python进程间通信:Queue

    Python进程间通信Queue 1.Queue使用方法: Queue.qsize():返回当前队列包含的消息数量: Queue.empty():如果队列为空,返回True,反之False : Que ...

  2. 【转】Django中的cookie与session

    转自:https://www.cnblogs.com/chenchao1990/p/5283725.html cookie与session的实现原理 HTTP被设计为”无状态”,每次请求都处于相同的空 ...

  3. ZOJ 1610.Count the Colors-线段树(区间染色、区间更新、单点查询)-有点小坑(染色片段)

    ZOJ Problem Set - 1610 Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting s ...

  4. ZOJ 3324 Machine

    线段树,延迟标记. 记录一下每个节点代表的区间的最小值,以及左右端点是否为最小值,记录区间被下压几次作为延迟标记,再记录一下这个区间中有多少个最小值的连通块. $n$最大有$1$亿,可以开动态线段树避 ...

  5. 永久修改IP地址

    第一种方法:使用nmtui文本框的方式修改IP 在命令行中输入nmtui,回车<Enter>会出现下图(英文的请自己对照,有点丑) 选择编辑 进入到如下界面,需要配置IPv4地址,要将IP ...

  6. WordPress漏洞扫描工具WPScan

    WordPress漏洞扫描工具WPScan   WordPress是主流的PHP网站模版,以构建博客而闻名.WordPress可以通过安装插件和主题的方式扩展功能,这也带来的安全隐患.WordPres ...

  7. poj 3225 Help with Intervals(线段树,区间更新)

    Help with Intervals Time Limit: 6000MS   Memory Limit: 131072K Total Submissions: 12474   Accepted:  ...

  8. 【推导】【暴力】Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) C. Five Dimensional Points

    题意:给你五维空间内n个点,问你有多少个点不是坏点. 坏点定义:如果对于某个点A,存在点B,C,使得角BAC为锐角,那么A是坏点. 结论:如果n维空间内已经存在2*n+1个点,那么再往里面添加任意多个 ...

  9. [转]Java transient关键字

    java 的transient关键字的作用是需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中. trans ...

  10. CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂

    772002画马尾 题目连接: http://acm.uestc.edu.cn/#/problem/show/1280 Description 众所周知772002很喜欢马尾,所以他决定画几幅马尾送给 ...