Skip to content

Commit

Permalink
Rails 7 support (#33)
Browse files Browse the repository at this point in the history
* First pass

* Update to support Rails 7

* Clean up version testing

* Update dependency location

* Update to support multiple Rails versions

* Update tests.yml

* Update abstract_mysql.rb
  • Loading branch information
noelrappin authored Jan 31, 2024
1 parent 125512d commit 89ef76e
Show file tree
Hide file tree
Showing 22 changed files with 119 additions and 91 deletions.
1 change: 1 addition & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DATABASE_URL="mysql2://root:@mysql/"
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ jobs:
strategy:
matrix:
ruby:
- '2.7'
- '3.0'
- '3.1'
- '3.2'
- '3.3'
rails:
- '6.0'
- '6.1'

- '7.0'
- '7.1'
runs-on: ubuntu-latest

name: RSpec (Rails ${{ matrix.rails }}) (Ruby ${{ matrix.ruby }})
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
.rspec_status

gemfiles/*.lock
.env.local
15 changes: 7 additions & 8 deletions Appraisals
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
appraise "rails-6.0" do
gem "rails", "~> 6.0.0"
appraise "rails-6.1" do
gem "rails", "~> 6.1"
end

appraise "rails-6.1" do
gem "rails", "~> 6.1.0"
appraise "rails-7.0" do
gem "rails", "~> 7.0"
end

# Rails 7.0 doesn't work yet
# appraise "rails-7.0" do
# gem "rails", "~> 7.0"
# end
appraise "rails-7.1" do
gem "rails", "~> 7.1"
end
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ RUN mkdir -p lib/sql_enum gemfiles
COPY lib/sql_enum/version.rb ./lib/sql_enum/
COPY gemfiles/*.gemfile gemfiles/
COPY sql_enum.gemspec Gemfile Gemfile.lock Appraisals ./
RUN bundle install && exec appraisal install
RUN bundle install && \
bundle exec appraisal install
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

# Specify your gem's dependencies in sql_enum.gemspec
gemspec
52 changes: 29 additions & 23 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,43 +1,48 @@
PATH
remote: .
specs:
sql_enum (0.4.0)
activerecord (>= 6.0, < 7.0)
activesupport (>= 6.0, < 7.0)
sql_enum (1.0.0)
activerecord (>= 6.1.0)
activesupport (>= 6.1.0)
mysql2

GEM
remote: https://rubygems.org/
specs:
activemodel (6.1.7.6)
activesupport (= 6.1.7.6)
activerecord (6.1.7.6)
activemodel (= 6.1.7.6)
activesupport (= 6.1.7.6)
activesupport (6.1.7.6)
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)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
appraisal (2.5.0)
bundler
rake
thor (>= 0.14.0)
concurrent-ruby (1.2.2)
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
awesome_print (1.9.2)
concurrent-ruby (1.2.3)
debug (1.9.1)
irb (~> 1.10)
reline (>= 0.3.8)
diff-lcs (1.5.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-console (0.6.0)
irb (1.7.4)
reline (>= 0.3.6)
minitest (5.19.0)
io-console (0.7.2)
irb (1.11.1)
rdoc
reline (>= 0.4.2)
minitest (5.21.2)
mysql2 (0.5.5)
rake (13.0.6)
reline (0.3.8)
psych (5.1.2)
stringio
rake (13.1.0)
rdoc (6.6.2)
psych (>= 4.0.0)
reline (0.4.2)
io-console (~> 0.5)
rspec (3.12.0)
rspec-core (~> 3.12.0)
Expand All @@ -52,22 +57,23 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
thor (1.2.2)
stringio (3.1.0)
thor (1.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
zeitwerk (2.6.11)

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
appraisal
awesome_print
bundler
debug
rake (~> 13.0)
rspec (~> 3.0)
sql_enum!

BUNDLED WITH
2.2.30
2.5.5
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Enables usage of native sql enums with ActiveRecord

## NOTE

Version 1.0 of this is compatible with Rails 7 and above.

For Rails versions below Rails 7, use version 0.4

## Installation

Add this line to your application's Gemfile:
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ services:

mysql:
image: mysql:5.7
platform: linux/amd64
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE
- MYSQL_USER
- MYSQL_PASSWORD
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
7 changes: 0 additions & 7 deletions gemfiles/rails_5.2.gemfile

This file was deleted.

7 changes: 0 additions & 7 deletions gemfiles/rails_6.0.gemfile

This file was deleted.

2 changes: 1 addition & 1 deletion gemfiles/rails_6.1.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.0"
gem "rails", "~> 6.1"

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/rails_7.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.0"
gem "rails", "~> 7.0"

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/rails_5.1.gemfile → 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", "~> 5.1.0"
gem "rails", "~> 7.1"

gemspec path: "../"
47 changes: 36 additions & 11 deletions lib/active_record/connection_adapters/abstract_mysql.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
# This module fails in Rails 7.0 becuase the method being modified has been
# changed to a class method.

module ActiveRecord
module ConnectionAdapters
class AbstractMysqlAdapter
def initialize_type_map_with_enum(m = type_map)
initialize_without_enum(m)
register_enum_type(m)
class << self
def register_enum_type(mapping)
mapping.register_type(%r(enum)i) do |sql_type|
Type::Enum.new(limit: sql_type.to_s.scan(/'(.*?)'/).flatten)
end
end
end

alias_method :initialize_without_enum, :initialize_type_map
alias_method :initialize_type_map, :initialize_type_map_with_enum
# 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.

def register_enum_type(mapping)
mapping.register_type(%r(enum)i) do |sql_type|
Type::Enum.new(limit: sql_type.scan(/'(.*?)'/).flatten)
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
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/sql_enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ 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
14 changes: 6 additions & 8 deletions lib/sql_enum/class_methods.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module SqlEnum
module ClassMethods
def sql_enum(column_name, options = {})
# skip redefinitions
return if defined_enums.key?(column_name.to_s)

# Query values
enum_column = EnumColumn.new(table_name, column_name)
values_map = enum_column.values.to_h { |value| [value.to_sym, value.to_s] }
Expand All @@ -14,20 +17,15 @@ def sql_enum(column_name, options = {})

# Override reader to return symbols
type_definition = ->(subtype) { EnumType.new(attr, send(column_name.to_s.pluralize), subtype) }
case method(:decorate_attribute_type).arity
when 2 # Rails 5.1, 5.2, 6.0
decorate_attribute_type(column_name, :enum, &type_definition)
else
decorate_attribute_type(column_name, &type_definition)
end
attribute(column_name, &type_definition)

prefix_str = format_affix(column_name, prefix, suffix: '_')
suffix_str = format_affix(column_name, suffix, prefix: '_')

# Fix query methods to compare symbols to symbols
values_map.each_value do |value|
method_name = "#{prefix_str}#{value}#{suffix_str}"
define_method("#{method_name}?") { self[column_name] == value.to_sym }
method_name = "#{prefix_str}#{value}#{suffix_str}?"
define_method(method_name) { self[column_name] == value.to_sym }
end
end

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 = "0.4.0"
VERSION = "1.0.0"
end
13 changes: 13 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require "sql_enum"

require 'debug'
require "awesome_print"

Dir['spec/support/**/*.rb'].each { |f| require File.expand_path(f) }

Expand All @@ -15,4 +16,16 @@
config.expect_with :rspec do |c|
c.syntax = :expect
end

# allow "fit" examples
config.filter_run_when_matching :focus
config.include DefineConstantMacros

config.before(:all) do
ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL'))
end

config.after do
clear_generated_tables
end
end
4 changes: 1 addition & 3 deletions spec/sql_enum_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
require 'spec_helper'

RSpec.describe SqlEnum do
it "has a version number" do
expect(SqlEnum::VERSION).not_to be_nil
Expand All @@ -11,12 +9,12 @@

before do
SqlEnum.configure { |config| config.default_prefix = true }

define_model('Task',
status: [:enum, limit: statuses, default: 'pending'],
priority: [:enum, limit: priorities]) do
sql_enum :status
sql_enum :priority, _prefix: false, _suffix: true
sql_enum :status # duplicate should be no-op
end
end

Expand Down
12 changes: 0 additions & 12 deletions spec/support/macros/define_constant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,3 @@ def created_tables
@created_tables ||= []
end
end

RSpec.configure do |config|
config.include DefineConstantMacros

config.before(:all) do
ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL'))
end

config.after do
clear_generated_tables
end
end
Loading

0 comments on commit 89ef76e

Please sign in to comment.