pg-enum 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b082cfa24cef44a2a3ba845c77487592d38f3c38
4
+ data.tar.gz: 6853f6d73ea44dab65af796c8e50767412a29eb5
5
+ SHA512:
6
+ metadata.gz: 9efcfc73fc57b672fad074f8059863808f336f922b02960269739f95d16fa4300ec9754fcdb9dc9c2d64dd2584e609e063fb511a7f5d093f85b76813508ffcdf
7
+ data.tar.gz: e68e047c7d4a8813a851511d804986532cbfa90c6172039a0f24087fb4c7f42ee97332e3ea18d3c6650fd22c8602aac4a50f1b1e612a479ba0950dc1ccdea20b
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # PgEnum
2
+
3
+ Add support for Postgres (enum)erated types to Active Record
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'pg-enum'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install pg-enum
20
+
21
+ ## Usage
22
+
23
+ Create an enum type like:
24
+
25
+ ```ruby
26
+ # db/migrate/20170818114925_add_status_to_conversations.rb
27
+ class AddStatusToConversations < ActiveRecord::Migration[5.1]
28
+ include PgEnum::MigrationHelpers
29
+
30
+ def up
31
+ create_enum :conversation_status, [:active, :archived]
32
+ add_column :conversations, :status, :conversation_status, default: "created"
33
+ end
34
+
35
+ def down
36
+ remove_column :conversations, :status
37
+ drop_enum :conversation_status
38
+ end
39
+ end
40
+ ```
41
+
42
+ To add PgEnum to an Active Record model, simply include the `PgEnum` module.
43
+
44
+ ```ruby
45
+ class Conversation < ActiveRecord::Base
46
+ include PgEnum
47
+
48
+ pg_enum :status
49
+ end
50
+ ```
51
+
52
+ The API is the same as [ActiveRecord::Enum](http://api.rubyonrails.org/classes/ActiveRecord/Enum.html).
53
+
54
+ ```ruby
55
+ Conversation.statuses
56
+ # => { active: 'active', archived: 'archived' }
57
+
58
+ conversation = Conversation.create
59
+ conversation.status # => "created"
60
+ conversation.created? # => true
61
+
62
+ conversation.archived!
63
+ conversation.status # => "archived"
64
+ conversation.archived? # => true
65
+
66
+ Conversation.active.count # => 0
67
+ Conversation.archived.count # => 1
68
+ ```
69
+
70
+ ## License
71
+
72
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/lib/pg-enum.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "pg_enum"
data/lib/pg_enum.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module PgEnum
6
+ extend ActiveSupport::Concern
7
+
8
+ ENUM_SQL = <<~SQL.squish
9
+ SELECT e.enumlabel
10
+ FROM pg_enum e
11
+ JOIN pg_type t
12
+ ON e.enumtypid = t.oid
13
+ WHERE t.typname = ?
14
+ SQL
15
+
16
+ class_methods do
17
+ def pg_enum(attr, options = {})
18
+ column = columns_hash[attr.to_s]
19
+
20
+ if column.nil? || column.type != :enum
21
+ raise "PgEnum: #{ model.table_name }.#{ attr } is not an enum"
22
+ end
23
+
24
+ enum(options.merge(column.name.to_sym => enum_values(column)))
25
+ end
26
+
27
+ private
28
+
29
+ def enum_values(column)
30
+ connection
31
+ .select_all(sanitize_sql_array([ENUM_SQL, column.sql_type]))
32
+ .map { |v| v["enumlabel"] }
33
+ .each_with_object({}) { |v, h| h[v.to_sym] = v }
34
+ end
35
+ end
36
+
37
+ module MigrationHelpers
38
+ def create_enum(name, values)
39
+ values = values.map { |v| "'#{ v }'" }
40
+
41
+ execute "CREATE TYPE #{ name } AS ENUM (#{ values.join(', ') })"
42
+ end
43
+
44
+ def drop_enum(name)
45
+ execute "DROP TYPE #{ name }"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+ require "active_record"
5
+ require "pg"
6
+ require "minitest/autorun"
7
+ require_relative "../lib/pg_enum"
8
+
9
+ configuration = {
10
+ "adapter" => "postgresql",
11
+ "database" => "pg_enum",
12
+ "host" => "localhost",
13
+ "port" => 5432
14
+ }
15
+
16
+ ActiveRecord::Base.establish_connection(configuration.merge(
17
+ "database" => "postgres",
18
+ "schema_search_path" => "public"
19
+ ))
20
+
21
+ ActiveRecord::Base.connection.drop_database(configuration["database"])
22
+
23
+ ActiveRecord::Base.connection.create_database(configuration["database"])
24
+
25
+ ActiveRecord::Base.establish_connection(configuration)
26
+
27
+ ActiveRecord::Schema.define do
28
+ execute "CREATE TYPE conversation_status AS ENUM ('active', 'archived')"
29
+
30
+ create_table :conversations, force: true do |t|
31
+ t.column :status, :conversation_status, default: "active"
32
+ end
33
+ end
34
+
35
+ class Conversation < ActiveRecord::Base
36
+ include PgEnum
37
+
38
+ pg_enum :status
39
+ end
40
+
41
+ class PgEnumTest < Minitest::Test
42
+ def setup
43
+ Conversation.delete_all
44
+ end
45
+
46
+ def test_default
47
+ assert_equal "active", Conversation.new.status
48
+ end
49
+
50
+ def test_enum_values
51
+ assert_equal "active", Conversation.statuses[:active]
52
+ assert_equal "archived", Conversation.statuses[:archived]
53
+ end
54
+
55
+ def test_scopes
56
+ conversation = Conversation.create!
57
+
58
+ assert_equal 1, Conversation.active.count
59
+ assert_equal 0, Conversation.archived.count
60
+
61
+ conversation = Conversation.create!(status: "archived")
62
+
63
+ assert_equal 1, Conversation.archived.count
64
+ end
65
+
66
+ def test_predicates
67
+ assert Conversation.new.active?
68
+ refute Conversation.new.archived?
69
+ end
70
+
71
+ def test_writter
72
+ conversation = Conversation.create!
73
+
74
+ assert_equal "active", conversation.status
75
+
76
+ conversation.archived!
77
+
78
+ assert_equal "archived", conversation.status
79
+ end
80
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pg-enum
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Francesco Rodríguez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.18'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.18'
41
+ - !ruby/object:Gem::Dependency
42
+ name: railties
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '4.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '4.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.15'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.15'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.49'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.49'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '12.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '12.0'
111
+ description: Adds support for Postgres (enum)erated types to Active Record
112
+ email: frodsan@protonmail.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - README.md
118
+ - lib/pg-enum.rb
119
+ - lib/pg_enum.rb
120
+ - test/pg_enum_test.rb
121
+ homepage: https://github.com/frodsan/pg-enum
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.6.13
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Adds support for Postgres (enum)erated types to Active Record
145
+ test_files:
146
+ - test/pg_enum_test.rb