|
|
|
Enum set type manager. For each enum-type created on the database, it allows 2 behaviors: Single enum attribution, Array (Set-like) attribution. For [Single enum attribution](https://github.com/crashtech/torque-postgresql/wiki/Enum) check the link. The enum type is known to have a better performance against string- and integer-like enums. Now with the array option, which behaves like binary assignment, each record can have multiple enum values. [PostgreSQL Docs](https://www.postgresql.org/docs/9.6/static/datatype-enum.html)
|
|
|
|
|
|
|
|
# How it works
|
|
|
|
|
|
|
|
### Migration
|
|
|
|
|
|
|
|
First, you have to create the enum during your migration, since it's the database that holds the list of possible values.
|
|
|
|
```ruby
|
|
|
|
create_enum :permissions, %i(read write exec)
|
|
|
|
```
|
|
|
|
|
|
|
|
You can check more about the type creation on the [Enum docs](https://github.com/crashtech/torque-postgresql/wiki/Enum).
|
|
|
|
|
|
|
|
Just as a reference, we will be using this table for the examples:
|
|
|
|
```ruby
|
|
|
|
create_table :posts do |t|
|
|
|
|
t.string :title
|
|
|
|
t.permissions :creator_permissions, array: true
|
|
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### The type Class
|
|
|
|
|
|
|
|
Each enum type loaded from the database will have its own class type of value for sets, created under the [`enum.namespace`](https://github.com/crashtech/torque-postgresql/wiki/Configuring#enum.namespace) namespace.
|
|
|
|
```ruby
|
|
|
|
Enum::PermissionsSet
|
|
|
|
|
|
|
|
# You can get a representative value from there
|
|
|
|
Enum::PermissionsSet.read
|
|
|
|
|
|
|
|
# Or you can get the list of values
|
|
|
|
Enum::PermissionsSet.values
|
|
|
|
|
|
|
|
# Allows you to iterate over the values directly from the class
|
|
|
|
Enum::PermissionsSet.each do |permission|
|
|
|
|
puts permission
|
|
|
|
end
|
|
|
|
|
|
|
|
# You can use index-based for power-based reference
|
|
|
|
Enum::PermissionsSet.new(0) # []
|
|
|
|
Enum::PermissionsSet.new(3) # [:read, :write]
|
|
|
|
Enum::PermissionsSet.exec.to_i # 4
|
|
|
|
```
|
|
|
|
|
|
|
|
### Models
|
|
|
|
|
|
|
|
You have to go to each of your models and enable the functionality for each enum-set-type field. You don't need to provide the values since they will be loaded from the database. The method name is defined on [`enum.set_method`](https://github.com/crashtech/torque-postgresql/wiki/Configuring#enum.set_method).
|
|
|
|
```ruby
|
|
|
|
# models/user.rb
|
|
|
|
class Post < ActiveRecord::Base
|
|
|
|
enum_set :creator_permissions
|
|
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
You are able to access the list of values trough the class that holds the enum set:
|
|
|
|
```ruby
|
|
|
|
Post.creator_permissions
|
|
|
|
```
|
|
|
|
|
|
|
|
You can set the column value from `String`, `Array`, `Symbol`, and `Integer`:
|
|
|
|
```ruby
|
|
|
|
post = Post.new
|
|
|
|
post.creator_permissions = 'read' # [:read]
|
|
|
|
post.creator_permissions = :write # [:write]
|
|
|
|
post.creator_permissions = [:read, :write] # [:read, :write]
|
|
|
|
post.creator_permissions = 7 # [:read, :write, :exec]
|
|
|
|
```
|
|
|
|
|
|
|
|
Given the power from the `to_i` operation, you can compare values, or make questions about it:
|
|
|
|
```ruby
|
|
|
|
other_post = Post.new(creator_permissions: [:read])
|
|
|
|
post = Post.new(creator_permissions: [:write])
|
|
|
|
post.creator_permissions > :exec # false
|
|
|
|
post.creator_permissions == 2 # true
|
|
|
|
post.creator_permissions >= other_post.creator_permissions # true
|
|
|
|
post.creator_permissions.write? # true
|
|
|
|
post.read? # false
|
|
|
|
```
|
|
|
|
|
|
|
|
The `bang!` methods are controlled by the [`enum.save_on_bang`](https://github.com/crashtech/torque-postgresql/wiki/Configuring#enum.save_on_bang):
|
|
|
|
```ruby
|
|
|
|
# The following will only perform a save on the database if enum.save_on_bang is set to true
|
|
|
|
post = Post.new(creator_permissions: [:write])
|
|
|
|
post.read!
|
|
|
|
post.creator_permissions === [:read, :write]
|
|
|
|
```
|
|
|
|
|
|
|
|
You can reach the I18n translations from three different ways, and the scopes are configured on [`enum.i18n_scopes`](https://github.com/crashtech/torque-postgresql/wiki/Configuring#enum.i18n_scopes). On the third one, only the scopes on [`enum.i18n_type_scope`](https://github.com/crashtech/torque-postgresql/wiki/Configuring#enum.i18n_type_scope) are used, that allows per-model customization.
|
|
|
|
```ruby
|
|
|
|
post = Post.new(creator_permissions: [:read, :write])
|
|
|
|
post.creator_permissions.text # Read post and Write post
|
|
|
|
post.creator_permissions_text # Read post and Write post
|
|
|
|
Enum::PermissionsSet.read.text # Read
|
|
|
|
```
|
|
|
|
|
|
|
|
### Set features
|
|
|
|
|
|
|
|
The value by itself behaves just like an [Set](https://ruby-doc.org/stdlib-2.5.1/libdoc/set/rdoc/Set.html), which allows all sorts of bitwise operations.
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
post = Post.new(creator_permissions: [:read, :write])
|
|
|
|
post.creator_permissions & [:write] # [:write]
|
|
|
|
post.creator_permissions & [:exec] # []
|
|
|
|
post.creator_permissions | [:exec] # [:read, :write, :exec]
|
|
|
|
post.creator_permissions -= :write # [:read]
|
|
|
|
```
|
|
|
|
|
|
|
|
### Testing
|
|
|
|
|
|
|
|
When testing models or creating records using factories, `EnumSet` provides an easy way to get a random number of values from the list of any enum types. Besides the normal `Post.creator_permissions.sample`, you can also use:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
Enum.sample(:permissions_set)
|
|
|
|
``` |