iangreenleaf / native_enum Goto Github PK
View Code? Open in Web Editor NEWAdds ENUM and SET support to ActiveRecord
License: MIT License
Adds ENUM and SET support to ActiveRecord
License: MIT License
@mcls @iangreenleaf just FYI I tried this gem with Rails 5.1, (and also with your new Rails 5.1 branch), and was getting ActiveRecord Validation failed
errors on my models (which I don't get using the original). This is occuring where I had e.g.
belongs_to :communication
Which I could solve by adding
belongs_to :communication, optional: true
However for models where I have
class Communication < ApplicationRecord
has_many :communications_stores
has_many :stores, -> { distinct },
through: :communications_stores
And I do
Communication.create(stores: stores)
It blew up. I couldn't work out how to stop it throwing the error in this case.
Hi there, I noticed that db:create is not working anymore
[00:11:36] blackfalcon:~/src/my_project/my_project :chris $ bin/rails db:create --trace
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:load_config
** Execute db:create
Database 'my_project' already exists
wrong number of arguments (given 0, expected 1)
Couldn't create database for {"encoding"=>"utf8", "pool"=>40, "timeout"=>5000, "adapter"=>"mysql2", "username"=>"root", "port"=>13306, "database"=>"my_project", "host"=>"mysql"}
rails aborted!
ArgumentError: wrong number of arguments (given 0, expected 1)
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/bundler/gems/native_enum-a9151d87527d/lib/native_enum/activerecord_enum_post42.rb:6:in `initialize_type_map_with_enum'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract_adapter.rb:524:in `reload_type_map'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:166:in `clear_cache!'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract_adapter.rb:392:in `disconnect!'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/mysql2_adapter.rb:103:in `disconnect!'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:438:in `block (3 levels) in disconnect'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:433:in `each'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:433:in `block (2 levels) in disconnect'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:432:in `block in disconnect'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:676:in `block in with_exclusively_acquired_all_connections'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:751:in `with_new_connections_blocked'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:674:in `with_exclusively_acquired_all_connections'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:431:in `disconnect'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:453:in `disconnect!'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:1025:in `remove_connection'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:952:in `establish_connection'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_handling.rb:60:in `establish_connection'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/mysql_database_tasks.rb:6:in `establish_connection'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/mysql_database_tasks.rb:13:in `create'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/database_tasks.rb:119:in `create'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/database_tasks.rb:139:in `block in create_current'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/database_tasks.rb:316:in `block in each_current_configuration'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/database_tasks.rb:313:in `each'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/database_tasks.rb:313:in `each_current_configuration'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/tasks/database_tasks.rb:138:in `create_current'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/railties/databases.rake:29:in `block (2 levels) in <main>'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:271:in `block in execute'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:271:in `each'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:271:in `execute'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:213:in `block in invoke_with_call_chain'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:193:in `invoke_with_call_chain'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/task.rb:182:in `invoke'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:160:in `invoke_task'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:116:in `each'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:116:in `block in top_level'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:125:in `run_with_threads'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:110:in `top_level'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rake-12.3.1/lib/rake/application.rb:186:in `standard_exception_handling'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/command.rb:48:in `invoke'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/commands.rb:18:in `<main>'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `block in require_with_bootsnap_lfi'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/loaded_features_index.rb:65:in `register'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:20:in `require_with_bootsnap_lfi'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:29:in `require'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `block in require'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:249:in `load_dependency'
/Users/chris/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:create
hmm, seems to brake during migration
create_table :users do |t|
t.enum :status, limit: ["active", "inactive"], default: "active", null: false
t.timestamps null: false
end
causes
undefined method `split' for nil:NilClass/Users/chris/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:695:in `block in initialize_type_map'
/Users/chris/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.4/lib/active_record/type/type_map.rb:53:in `call'
/Users/chris/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.4/lib/active_record/type/type_map.rb:53:in `perform_fetch'
This doesn't work with rails4.2-beta1
Add code for this adapter.
Looks like PostgreSQL has support for ENUM types, not sure about SET.
works with ruby 2.7 and rails 6.0
vendor/bundle/ruby/3.0.0/gems/activerecord-6.0.6.1/lib/active_record/connection_adapters/mysql/schema_statements.rb:101:in `type_to_sql'
vendor/bundle/ruby/3.0.0/gems/native_enum-2.0.0/lib/connection_adapters/mysql2.rb:40:in `type_to_sql_with_enum'
vendor/bundle/ruby/3.0.0/gems/activerecord-6.0.6.1/lib/active_record/connection_adapters/abstract/schema_creation.rb:17:in `type_to_sql'
vendor/bundle/ruby/3.0.0/gems/activerecord-6.0.6.1/lib/active_record/connection_adapters/abstract/schema_creation.rb:30:in `visit_ColumnDefinition'
The introduction of psuedo-enum support in 4.1 calls for some clarification of what role this gem should play.
I think the core purpose of this gem is still valuable, since Active Record's stuff seems aimed at integer columns, not actual ENUMs. So it seems that it should stick around and not be dropped entirely. But I should add a section to the README that explains this for people who might be confused.
I might also need to consider changing to name to reduce confusion.
I am currently using rails 5.1.2, ruby 2.4.1
I tried to run the following migration:
class AddUsersOneTimeStatus < ActiveRecord::Migration[5.1]
def change
change_column :users, :status, :enum, limit: %w(active one_time inactive), default: 'active', null: false
end
end
which caused the following error:
Mysql2::Error: Invalid default value for 'status': ALTER TABLE `users` CHANGE `status` `status` enum('[:limit, ["active", "one_time", "inactive"]]','[:default, "active"]','[:null, false]','[:comment, nil]','[:primary_key, false]') DEFAULT 'active' NOT NULL
/no/need/to/know/db/migrate/20170626163720_add_users_one_time_status.rb:3:in `change'
ActiveRecord::StatementInvalid: Mysql2::Error: Invalid default value for 'status': ALTER TABLE `users` CHANGE `status` `status` enum('[:limit, ["active", "one_time", "inactive"]]','[:default, "active"]','[:null, false]','[:comment, nil]','[:primary_key, false]') DEFAULT 'active' NOT NULL
This problem occurs because the parameters of ActiveRecord::ConnectionAdapters#type_to_sql
changed from type, limit=nil, *args
to (type, limit: nil, precision: nil, scale: nil, unsigned: nil, **)
. This is caused by the following change in activerecord 5.1:
rails/rails@ae39b1a#diff-98ce5dc0cd01f8b0435ff6feac10d8a8
monkey patch (please this e.g. inside config/initializers/):
# monkey patch for native_enum-1.0.0
# fixes change_column bug - https://github.com/iangreenleaf/native_enum/issues/11
require 'native_enum'
require 'connection_adapters/mysql2'
module ActiveRecord
module ConnectionAdapters
existing_class = defined?( Mysql2Adapter ) ? Mysql2Adapter : AbstractMysqlAdapter
existing_class.class_eval do
# def type_to_sql_with_enum type, limit=nil, *args
def type_to_sql_with_enum_fix(type, limit: nil, **options)
if type.to_s == "enum" || type.to_s == "set"
"#{type}(#{quoted_comma_list limit})"
else
type_to_sql_without_enum type, limit: limit, **options
end
end
alias_method :type_to_sql, :type_to_sql_with_enum_fix
end
end
end
The class structure in AR 3.1.x has changed significantly. Work in support for that series without dropping support for 3.0.x.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.