Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ jobs:
strategy:
matrix:
ruby:
- '3.0'
- '3.1'
- '3.2'
- '3.3'
- '3.4'
- '4.0'
rails:
- '6.1'
- '7.0'
- '7.1'
- '7.2'
- '8.0'
- '8.1'
runs-on: ubuntu-22.04

name: RSpec (Rails ${{ matrix.rails }}) (Ruby ${{ matrix.ruby }})
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@

gemfiles/*.lock
.env.local
*.gem
/.claude
16 changes: 10 additions & 6 deletions Appraisals
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
appraise "rails-6.1" do
gem "rails", "~> 6.1"
appraise "rails-7.1" do
gem "rails", "~> 7.1.0"
end

appraise "rails-7.0" do
gem "rails", "~> 7.0"
appraise "rails-7.2" do
gem "rails", "~> 7.2.0"
end

appraise "rails-7.1" do
gem "rails", "~> 7.1"
appraise "rails-8.0" do
gem "rails", "~> 8.0.0"
end

appraise "rails-8.1" do
gem "rails", "~> 8.1.0"
end
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ruby:3.0
FROM ruby:3.4

WORKDIR /usr/src/app

Expand Down
46 changes: 33 additions & 13 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,42 +1,59 @@
PATH
remote: .
specs:
sql_enum (1.0.0)
activerecord (>= 6.1.0)
activesupport (>= 6.1.0)
sql_enum (2.0.0)
activerecord (>= 7.1.0)
activesupport (>= 7.1.0)
mysql2

GEM
remote: https://rubygems.org/
specs:
activemodel (7.0.8)
activesupport (= 7.0.8)
activerecord (7.0.8)
activemodel (= 7.0.8)
activesupport (= 7.0.8)
activesupport (7.0.8)
concurrent-ruby (~> 1.0, >= 1.0.2)
activemodel (8.1.2)
activesupport (= 8.1.2)
activerecord (8.1.2)
activemodel (= 8.1.2)
activesupport (= 8.1.2)
timeout (>= 0.4.0)
activesupport (8.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
json
logger (>= 1.4.2)
minitest (>= 5.1)
tzinfo (~> 2.0)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
appraisal (2.5.0)
bundler
rake
thor (>= 0.14.0)
awesome_print (1.9.2)
concurrent-ruby (1.2.3)
base64 (0.3.0)
bigdecimal (4.0.1)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
debug (1.9.1)
irb (~> 1.10)
reline (>= 0.3.8)
diff-lcs (1.5.0)
drb (2.2.3)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-console (0.7.2)
irb (1.11.1)
rdoc
reline (>= 0.4.2)
minitest (5.21.2)
json (2.18.1)
logger (1.7.0)
minitest (6.0.1)
prism (~> 1.5)
mysql2 (0.5.5)
prism (1.9.0)
psych (5.1.2)
stringio
rake (13.1.0)
Expand All @@ -57,10 +74,13 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
securerandom (0.4.1)
stringio (3.1.0)
thor (1.3.0)
timeout (0.6.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uri (1.1.1)

PLATFORMS
ruby
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Enables usage of native sql enums with ActiveRecord

## NOTE

Version 1.0 of this is compatible with Rails 7 and above.
Version 2.0 of this gem requires Rails 7.1+ and Ruby 3.2+.

For Rails versions below Rails 7, use version 0.4
For Rails 7.0 and 7.1, use version 1.0. For Rails versions below 7, use version 0.4.

## Installation

Expand All @@ -30,7 +30,7 @@ Or install it yourself as:

Use a part of table definition:
```ruby
class CreateUsers < ActiveRecord::Migration[5.1]
class CreateUsers < ActiveRecord::Migration[7.1]
def change
create_table :users do |t|
t.enum :status, limit: [:active, :pending, :inactive], default: :active
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails_7.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

source "https://rubygems.org"

gem "rails", "~> 7.1"
gem "rails", "~> 7.1.0"

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/rails_6.1.gemfile → gemfiles/rails_7.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

source "https://rubygems.org"

gem "rails", "~> 6.1"
gem "rails", "~> 7.2.0"

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/rails_7.0.gemfile → gemfiles/rails_8.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

source "https://rubygems.org"

gem "rails", "~> 7.0"
gem "rails", "~> 8.0.0"

gemspec path: "../"
7 changes: 7 additions & 0 deletions gemfiles/rails_8.1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "rails", "~> 8.1.0"

gemspec path: "../"
37 changes: 4 additions & 33 deletions lib/active_record/connection_adapters/abstract_mysql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,10 @@ def register_enum_type(mapping)
end
end

# In Rails 6.1, registering the enum type is an instance method and is
# done on initialization, In Rails 7.0 it is a class method and
# the registration happens when the class is loaded. So, in Rails 6.1,
# we can override the `initialize_type_map` method to register the enum
# but in Rails 7.1, we need to call register_enum_type explicitly.

if SqlEnum.rails_version_match?("6.1")
module SqlEnumMapper
def initialize_type_map(m = type_map)
super(m)
AbstractMysqlAdapter.register_enum_type(m)
end
end

ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(SqlEnumMapper)
end


if SqlEnum.rails_version_match?("7.0")
[
ActiveRecord::ConnectionAdapters::Mysql2Adapter::TYPE_MAP,
ActiveRecord::ConnectionAdapters::Mysql2Adapter::TYPE_MAP_WITH_BOOLEAN
].each do |m|
AbstractMysqlAdapter.register_enum_type(m)
end
end

# Rails 7.1 drops the TYPE_MAP_WITH_BOOLEAN constant
if SqlEnum.rails_version_match?("7.1")
AbstractMysqlAdapter.register_enum_type(
ActiveRecord::ConnectionAdapters::Mysql2Adapter::TYPE_MAP
)
end
# Rails 7.1+ uses a single TYPE_MAP constant on the adapter class
AbstractMysqlAdapter.register_enum_type(
ActiveRecord::ConnectionAdapters::Mysql2Adapter::TYPE_MAP
)
end
end
end
15 changes: 8 additions & 7 deletions lib/active_record/connection_adapters/mysql2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ def native_database_types
self.class::NATIVE_DATABASE_TYPES.merge(enum: {name: "enum"})
end

def type_to_sql_with_enum(type, limit: nil, precision: nil, scale: nil, unsigned: nil, **)
if type.to_sym == :enum
"#{type}(#{limit.map{|n| "'#{n}'"}.join(",")})"
else
type_to_sql_without_enum(type, limit: limit, precision: precision, scale: scale, unsigned: unsigned)
module SqlEnumTypeToSql
def type_to_sql(type, limit: nil, **)
if type.to_sym == :enum
"#{type}(#{limit.map { |n| "'#{n}'" }.join(",")})"
else
super
end
end
end

alias_method :type_to_sql_without_enum, :type_to_sql
alias_method :type_to_sql, :type_to_sql_with_enum
prepend SqlEnumTypeToSql
end
end
end
4 changes: 0 additions & 4 deletions lib/sql_enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ def self.configure
self.configuration ||= Configuration.new
yield(configuration)
end

def self.rails_version_match?(version_string)
ActiveSupport.version.to_s.start_with?(version_string)
end
end

require 'active_record'
Expand Down
15 changes: 12 additions & 3 deletions lib/sql_enum/class_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ def sql_enum(column_name, options = {})
suffix = options.fetch(:_suffix, !!SqlEnum.configuration&.default_suffix)

# Define enum using Rails enum
enum(column_name => values_map, _prefix: prefix, _suffix: suffix)
enum(column_name, values_map, prefix: prefix, suffix: suffix)

# Override reader to return symbols
type_definition = ->(subtype) { EnumType.new(attr, send(column_name.to_s.pluralize), subtype) }
attribute(column_name, &type_definition)
col_name = column_name.to_s
enum_type = ->(subtype) do
subtype = subtype.subtype if ActiveRecord::Enum::EnumType === subtype
EnumType.new(col_name, send(col_name.pluralize), subtype)
end

if respond_to?(:decorate_attributes, true)
decorate_attributes([col_name]) { |_name, subtype| enum_type.call(subtype) }
else
attribute(column_name, &enum_type)
end

prefix_str = format_affix(column_name, prefix, suffix: '_')
suffix_str = format_affix(column_name, suffix, prefix: '_')
Expand Down
12 changes: 6 additions & 6 deletions lib/sql_enum/enum_column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ def values
private

def schema_values
ActiveRecord::Base.connection.exec_query(schema_values_query).rows.dig(0, 0)
if ActiveRecord::Base.respond_to?(:with_connection)
ActiveRecord::Base.with_connection { |conn| conn.exec_query(schema_values_query).rows.dig(0, 0) }
else
ActiveRecord::Base.connection.exec_query(schema_values_query).rows.dig(0, 0)
end
end

def database_name
if ActiveRecord::Base.respond_to?(:connection_db_config)
ActiveRecord::Base.connection_db_config.configuration_hash[:database]
else
ActiveRecord::Base.connection_config.values_at(:database, :database_name).find(&:present?)
end
ActiveRecord::Base.connection_db_config.configuration_hash[:database]
end

def schema_values_query
Expand Down
2 changes: 1 addition & 1 deletion lib/sql_enum/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module SqlEnum
VERSION = "1.0.0"
VERSION = "2.0.0"
end
Binary file added sql_enum-1.0.0.gem
Binary file not shown.
6 changes: 4 additions & 2 deletions sql_enum.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.required_ruby_version = ">= 3.2.0"

spec.add_dependency "mysql2"
spec.add_dependency "activesupport", ">= 6.1.0"
spec.add_dependency "activerecord", ">= 6.1.0"
spec.add_dependency "activesupport", ">= 7.1.0"
spec.add_dependency "activerecord", ">= 7.1.0"

spec.add_development_dependency "appraisal"
spec.add_development_dependency "awesome_print"
Expand Down