From 027e21ff77b0a7c4000a08ac191f75c269c7c56d Mon Sep 17 00:00:00 2001 From: khiav reoy Date: Sun, 30 Jul 2023 13:47:20 +0800 Subject: [PATCH 1/5] refactoring by adding cast_values method --- gemfiles/active_record_70.gemfile | 2 +- lib/pluck_all/models/active_record_extension.rb | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/gemfiles/active_record_70.gemfile b/gemfiles/active_record_70.gemfile index 8e3635c..e49e4b5 100644 --- a/gemfiles/active_record_70.gemfile +++ b/gemfiles/active_record_70.gemfile @@ -4,7 +4,7 @@ source 'https://rubygems.org' gem 'sqlite3', '~> 1.4.1' gem 'zeitwerk' -gem 'activerecord', '~> 7.0.0' +gem 'activerecord', '~> 7.0.6' gem 'rails_compatibility', '~> 0.0.7' gem 'carrierwave', '~> 0.11.0' diff --git a/lib/pluck_all/models/active_record_extension.rb b/lib/pluck_all/models/active_record_extension.rb index 4bc8ff2..ed88a47 100644 --- a/lib/pluck_all/models/active_record_extension.rb +++ b/lib/pluck_all/models/active_record_extension.rb @@ -57,18 +57,24 @@ def pluck_all(*column_names, cast_uploader_url: true) return RailsCompatibility.apply_join_dependency(self).pluck_all(*column_names) if has_include result = select_all(column_names) + return cast_values(result, cast_uploader_url) + end + + private + + # Please refer to the 'cast_values' method in the 'active_record/result.rb' file to see the original implementation of `pluck` method. + def cast_values(result, cast_uploader_url) attribute_types = RailsCompatibility.attribute_types(klass) + result.map do |attributes| # This map behaves different to array#map attributes.each do |key, attribute| - attributes[key] = result.send(:column_type, key, attribute_types).deserialize(attribute) # TODO: 現在AS過後的type cast會有一點問題,但似乎原生的pluck也有此問題 + attributes[key] = result.send(:column_type, key, attribute_types).deserialize(attribute) end cast_carrier_wave_uploader_url(attributes) if cast_uploader_url next attributes end end - private - def to_sql_column_name proc do |column_name| if column_name.is_a?(Arel::Attributes::Attribute) From bc2b9d1be21dd3c1917d3049a64186bd8bab41d6 Mon Sep 17 00:00:00 2001 From: khiav reoy Date: Sun, 30 Jul 2023 16:04:47 +0800 Subject: [PATCH 2/5] Fix the parameters problem when casting values --- .../models/active_record_extension.rb | 33 +++++-------------- lib/pluck_all/models/patches/deserialize.rb | 13 -------- pluck_all.gemspec | 2 +- 3 files changed, 10 insertions(+), 38 deletions(-) delete mode 100644 lib/pluck_all/models/patches/deserialize.rb diff --git a/lib/pluck_all/models/active_record_extension.rb b/lib/pluck_all/models/active_record_extension.rb index ed88a47..35f1986 100644 --- a/lib/pluck_all/models/active_record_extension.rb +++ b/lib/pluck_all/models/active_record_extension.rb @@ -1,7 +1,6 @@ -require 'rails_compatibility/attribute_types' require 'rails_compatibility/has_include' require 'rails_compatibility/apply_join_dependency' -require_relative 'patches/deserialize' +require 'rails_compatibility/cast_values' class ActiveRecord::Relation def cast_need_columns(column_names, _klass = nil) @@ -28,14 +27,10 @@ def select_all(column_names) if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.0.0') def pluck_all(*column_names, cast_uploader_url: true) result = select_all(column_names) - result.map! do |attributes| # This map! behaves different to array#map! - initialized_attributes = klass.initialize_attributes(attributes) - attributes.each do |key, _attribute| - attributes[key] = klass.type_cast_attribute(key, initialized_attributes) # TODO: 現在AS過後的type cast會有一點問題 - end - cast_carrier_wave_uploader_url(attributes) if cast_uploader_url - next attributes - end + casted_result = RailsCompatibility.cast_values(klass, result) + + casted_result.each{|attributes| cast_carrier_wave_uploader_url(attributes) } if cast_uploader_url + return casted_result end private @@ -57,24 +52,14 @@ def pluck_all(*column_names, cast_uploader_url: true) return RailsCompatibility.apply_join_dependency(self).pluck_all(*column_names) if has_include result = select_all(column_names) - return cast_values(result, cast_uploader_url) + casted_result = RailsCompatibility.cast_values(klass, result) + + casted_result.each{|attributes| cast_carrier_wave_uploader_url(attributes) } if cast_uploader_url + return casted_result end private - # Please refer to the 'cast_values' method in the 'active_record/result.rb' file to see the original implementation of `pluck` method. - def cast_values(result, cast_uploader_url) - attribute_types = RailsCompatibility.attribute_types(klass) - - result.map do |attributes| # This map behaves different to array#map - attributes.each do |key, attribute| - attributes[key] = result.send(:column_type, key, attribute_types).deserialize(attribute) - end - cast_carrier_wave_uploader_url(attributes) if cast_uploader_url - next attributes - end - end - def to_sql_column_name proc do |column_name| if column_name.is_a?(Arel::Attributes::Attribute) diff --git a/lib/pluck_all/models/patches/deserialize.rb b/lib/pluck_all/models/patches/deserialize.rb deleted file mode 100644 index b06abec..0000000 --- a/lib/pluck_all/models/patches/deserialize.rb +++ /dev/null @@ -1,13 +0,0 @@ -module ActiveRecord - [ - *([Type::Value, Type::Integer, Type::Serialized] if defined?(Type::Value)), - *([Enum::EnumType] if defined?(Enum::EnumType)), - ].each do |s| - s.class_eval do - if !method_defined?(:deserialize) && method_defined?(:type_cast_from_database) - # deserialize was changed to type_cast_from_database in Rails 5 - alias_method :deserialize, :type_cast_from_database - end - end - end -end diff --git a/pluck_all.gemspec b/pluck_all.gemspec index 00f6548..af8537e 100644 --- a/pluck_all.gemspec +++ b/pluck_all.gemspec @@ -35,7 +35,7 @@ Gem::Specification.new do |spec| } spec.add_dependency 'activesupport', '>= 3.0.0' - spec.add_dependency 'rails_compatibility', '>= 0.0.8' + spec.add_dependency 'rails_compatibility', '>= 0.0.10' spec.add_development_dependency 'bundler', '>= 1.17', '< 3.x' spec.add_development_dependency 'rake', '~> 12.0' From ec68b3759748819a44fb85926b63550bcc49424a Mon Sep 17 00:00:00 2001 From: khiav reoy Date: Sun, 30 Jul 2023 16:07:36 +0800 Subject: [PATCH 3/5] Drop the support of Ruby 2.2 Since github flow fails to install bundler in Ruby 2.2. The error message: Bundler 2 requires Ruby 2.3+, using Bundler 1 on Ruby <= 2.2 /opt/hostedtoolcache/Ruby/2.2.10/x64/bin/gem install bundler -v ~> 1.0 ERROR: While executing gem ... (RuntimeError) Marshal.load reentered at marshal_load Took 0.42 seconds Error: The process '/opt/hostedtoolcache/Ruby/2.2.10/x64/bin/gem' failed with exit code 1 --- .github/workflows/ruby.yml | 10 ++++------ README.md | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 6d92296..d49fda0 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -23,7 +23,7 @@ jobs: - ACTIVE_RECORD - MONGOID ruby: - - 2.2 + - 2.3 - 2.6 - 2.7 - 3.0 @@ -78,15 +78,15 @@ jobs: - gemfile: active_record_52.gemfile orm: MONGOID - gemfile: active_record_60.gemfile - ruby: 2.2 + ruby: 2.3 - gemfile: active_record_60.gemfile orm: MONGOID - gemfile: active_record_61.gemfile - ruby: 2.2 + ruby: 2.3 - gemfile: active_record_61.gemfile orm: MONGOID - gemfile: active_record_70.gemfile - ruby: 2.2 + ruby: 2.3 - gemfile: active_record_70.gemfile ruby: 2.6 - gemfile: active_record_70.gemfile @@ -97,8 +97,6 @@ jobs: ruby: 3.0 - gemfile: mongoid_54.gemfile ruby: 3.1 - - gemfile: mongoid_73.gemfile - ruby: 2.2 - gemfile: mongoid_54.gemfile orm: ACTIVE_RECORD - gemfile: mongoid_64.gemfile diff --git a/README.md b/README.md index 899930a..e4f5697 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ If you have a Rails 3 project, and want to pluck not only one column, feel free to use this gem and no need to worry about upgrading to Rails 4, 5, 6 in the future will break this. ## Supports -- Ruby 2.2 ~ 2.7, 3.0 ~ 3.1 +- Ruby 2.3 ~ 2.7, 3.0 ~ 3.1 - Rails 3.2, 4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0 ## Installation From 83970851827884ce971221c986474eda81371b90 Mon Sep 17 00:00:00 2001 From: khiav reoy Date: Sun, 30 Jul 2023 16:34:01 +0800 Subject: [PATCH 4/5] Fix: Psych::DisallowedClass --- test/active_record/support/seeds.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/active_record/support/seeds.rb b/test/active_record/support/seeds.rb index 4f18a45..5a5bb12 100644 --- a/test/active_record/support/seeds.rb +++ b/test/active_record/support/seeds.rb @@ -21,6 +21,8 @@ end end +ActiveRecord::Base.use_yaml_unsafe_load = true if ActiveRecord::Base.method_defined?(:use_yaml_unsafe_load) + users = User.create([ { name: 'John', email: 'john@example.com' }, { name: 'Pearl', email: 'pearl@example.com', serialized_attribute: { testing: true, deep: { deep: :deep }}}, From 300047ea29021558c3bfe54ca1492548fdfed762 Mon Sep 17 00:00:00 2001 From: khiav reoy Date: Sun, 30 Jul 2023 16:59:03 +0800 Subject: [PATCH 5/5] Fix: uninitialized constant User In the test setting Test (MONGOID, 3.1, mongoid_73.gemfile) got this error: SimpleCov failed with exit 1/home/runner/work/pluck_all/pluck_all/test/mongoid/support/seeds.rb:2:in `': uninitialized constant User (NameError) --- gemfiles/mongoid_73.gemfile | 5 +++++ test/mongoid/support/seeds.rb | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/gemfiles/mongoid_73.gemfile b/gemfiles/mongoid_73.gemfile index a35e108..1beef0c 100644 --- a/gemfiles/mongoid_73.gemfile +++ b/gemfiles/mongoid_73.gemfile @@ -4,6 +4,11 @@ source 'https://rubygems.org' gem 'mongoid', '~> 7.3.3' +# We need zeitwerk for autoloading in Rails 7 +# But zeitwerk required ruby >= 2.4.4, we cannot test it in ruby 2.3 +# So we lock the version below 7 +gem 'activesupport', '< 7' + group :test do gem 'simplecov', '< 0.18' end diff --git a/test/mongoid/support/seeds.rb b/test/mongoid/support/seeds.rb index 318c77c..e2aa7c8 100644 --- a/test/mongoid/support/seeds.rb +++ b/test/mongoid/support/seeds.rb @@ -1,4 +1,8 @@ # frozen_string_literal: true + +require 'rails_compatibility/setup_autoload_paths' +RailsCompatibility.setup_autoload_paths [File.expand_path('../models/', __FILE__)] + User.delete_all User.create(name: 'Pearl Shi', age: 18) User.create(name: 'Rumble Huang', age: 20)