pluck_all 2.0.1 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ module PluckAll
2
+ class Hooks
3
+ class << self
4
+ def init
5
+ require 'pluck_all/models/active_record_extension' if require_if_exists('active_record')
6
+ require 'pluck_all/models/mongoid_extension' if require_if_exists('mongoid')
7
+ end
8
+
9
+ private
10
+
11
+ def require_if_exists(path)
12
+ require path
13
+ return true
14
+ rescue LoadError, Gem::LoadError
15
+ return false
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ PluckAll::Hooks.init
@@ -0,0 +1,131 @@
1
+ require 'rails_compatibility/attribute_types'
2
+ require_relative 'patches/deserialize'
3
+
4
+ class ActiveRecord::Relation
5
+ def cast_need_columns(column_names, _klass = nil)
6
+ @pluck_all_cast_need_columns = column_names.map(&:to_s)
7
+ @pluck_all_cast_klass = _klass
8
+ return self
9
+ end
10
+
11
+ def select_all(*column_names)
12
+ relation = clone
13
+ relation.select_values = [].freeze # cannot use `unscope(:select)` in Rails 3
14
+ return klass.connection.select_all(relation.select(column_names).to_sql)
15
+ end
16
+
17
+ if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.0.0')
18
+ def pluck_all(*column_names, cast_uploader_url: true)
19
+ column_names.map!(&to_sql_column_name)
20
+ result = select_all(*column_names)
21
+ result.map! do |attributes| # This map! behaves different to array#map!
22
+ initialized_attributes = klass.initialize_attributes(attributes)
23
+ attributes.each do |key, _attribute|
24
+ attributes[key] = klass.type_cast_attribute(key, initialized_attributes) # TODO: 現在AS過後的type cast會有一點問題
25
+ end
26
+ cast_carrier_wave_uploader_url(attributes) if cast_uploader_url
27
+ next attributes
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def to_sql_column_name
34
+ proc do |column_name|
35
+ if column_name.is_a?(Arel::Attributes::Attribute)
36
+ "#{column_name.relation.name}.#{column_name.name}"
37
+ elsif column_name.is_a?(Symbol) && column_names.include?(column_name.to_s)
38
+ "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
39
+ else
40
+ column_name.to_s
41
+ end
42
+ end
43
+ end
44
+ else
45
+ def pluck_all(*column_names, cast_uploader_url: true)
46
+ column_names.map!(&to_sql_column_name)
47
+ if has_include?(column_names.first)
48
+ # The `construct_relation_for_association_calculations` method was removed at Rails 5.2.
49
+ relation = Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('5.2.0') ? apply_join_dependency : construct_relation_for_association_calculations
50
+ return relation.pluck_all(*column_names)
51
+ end
52
+ result = select_all(*column_names)
53
+ attribute_types = RailsCompatibility.attribute_types(klass)
54
+ result.map do |attributes| # This map behaves different to array#map
55
+ attributes.each do |key, attribute|
56
+ attributes[key] = result.send(:column_type, key, attribute_types).deserialize(attribute) # TODO: 現在AS過後的type cast會有一點問題,但似乎原生的pluck也有此問題
57
+ end
58
+ cast_carrier_wave_uploader_url(attributes) if cast_uploader_url
59
+ next attributes
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def to_sql_column_name
66
+ proc do |column_name|
67
+ if column_name.is_a?(Arel::Attributes::Attribute)
68
+ "#{column_name.relation.name}.#{column_name.name}"
69
+ elsif column_name.is_a?(Symbol) && attribute_alias?(column_name)
70
+ attribute_alias(column_name)
71
+ else
72
+ column_name.to_s
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ # ----------------------------------------------------------------
79
+ # ● Support casting CarrierWave url
80
+ # ----------------------------------------------------------------
81
+ def cast_carrier_wave_uploader_url(attributes)
82
+ if defined?(CarrierWave) && klass.respond_to?(:uploaders)
83
+ @pluck_all_cast_need_columns ||= nil
84
+ @pluck_all_cast_klass ||= klass
85
+ @pluck_all_uploaders ||= @pluck_all_cast_klass.uploaders.select{|key, _uploader| attributes.key?(key.to_s) }
86
+ @pluck_all_uploaders.each do |key, _uploader|
87
+ {}.tap do |hash|
88
+ @pluck_all_cast_need_columns.each{|k| hash[k] = attributes[k] } if @pluck_all_cast_need_columns
89
+ obj = @pluck_all_cast_klass.instantiate(hash)
90
+ obj[key] = attributes[key_s = key.to_s]
91
+ # https://github.com/carrierwaveuploader/carrierwave/blob/87c37b706c560de6d01816f9ebaa15ce1c51ed58/lib/carrierwave/mount.rb#L142
92
+ attributes[key_s] = obj.send(key)
93
+ end
94
+ end
95
+ end
96
+ return attributes
97
+ end
98
+ end
99
+
100
+ class ActiveRecord::Relation
101
+ if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.0.2')
102
+ def pluck_array(*args)
103
+ return pluck_all(*args, cast_uploader_url: false).map do |hash|
104
+ result = hash.values # P.S. 這裡是相信ruby 1.9以後,hash.values的順序跟insert的順序一樣。
105
+ next (args.one? ? result.first : result)
106
+ end
107
+ end
108
+ else
109
+ alias pluck_array pluck if not method_defined?(:pluck_array)
110
+ end
111
+ end
112
+
113
+ class << ActiveRecord::Base
114
+ def cast_need_columns(*args)
115
+ where(nil).cast_need_columns(*args)
116
+ end
117
+
118
+ def pluck_all(*args)
119
+ where(nil).pluck_all(*args)
120
+ end
121
+
122
+ def pluck_array(*args)
123
+ where(nil).pluck_array(*args)
124
+ end
125
+ end
126
+
127
+ module ActiveRecord::NullRelation
128
+ def pluck_all(*_args)
129
+ []
130
+ end
131
+ end
@@ -1,5 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
  module Mongoid
3
+ module Document::ClassMethods
4
+ def pluck_array(*fields)
5
+ where(nil).pluck_array(*fields)
6
+ end
7
+
8
+ def pluck_all(*fields)
9
+ where(nil).pluck_all(*fields)
10
+ end
11
+ end
12
+
3
13
  module Findable
4
14
  delegate :pluck_all, :pluck_array, to: :with_default_scope
5
15
  end
@@ -21,9 +31,7 @@ module Mongoid
21
31
  def pluck_array(*fields)
22
32
  normalized_select = get_normalized_select(fields)
23
33
  get_query_data(normalized_select).reduce([]) do |plucked, doc|
24
- values = normalized_select.keys.map do |n|
25
- n =~ /\./ ? doc[n.partition('.')[0]] : doc[n]
26
- end
34
+ values = normalized_select.keys.map(&plucked_value_mapper(:array, doc))
27
35
  plucked << (values.size == 1 ? values.first : values)
28
36
  end
29
37
  end
@@ -31,23 +39,30 @@ module Mongoid
31
39
  def pluck_all(*fields)
32
40
  normalized_select = get_normalized_select(fields)
33
41
  get_query_data(normalized_select).reduce([]) do |plucked, doc|
34
- values = normalized_select.keys.map do |n|
35
- [n, n =~ /\./ ? doc[n.partition('.')[0]] : doc[n]]
36
- end.to_h
37
- plucked << values
42
+ values = normalized_select.keys.map(&plucked_value_mapper(:all, doc))
43
+ plucked << values.to_h
38
44
  end
39
45
  end
40
46
 
41
47
  private
42
48
 
49
+ def plucked_value_mapper(type, doc)
50
+ proc do |n|
51
+ values = [n, n =~ /\./ ? doc[n.partition('.')[0]] : doc[n]]
52
+ case type
53
+ when :array then values[1]
54
+ when :all then values
55
+ end
56
+ end
57
+ end
58
+
43
59
  def get_query_data(normalized_select)
44
60
  return (@view ? @view.projection(normalized_select) : query.dup.select(normalized_select))
45
61
  end
46
62
 
47
63
  def get_normalized_select(fields)
48
- normalized_select = fields.inject({}) do |hash, f|
64
+ fields.each_with_object({}) do |f, hash|
49
65
  hash[klass.database_field_name(f)] = 1
50
- hash
51
66
  end
52
67
  end
53
68
  end
@@ -0,0 +1,13 @@
1
+ module ActiveRecord
2
+ [
3
+ *([Type::Value, Type::Integer, Type::Serialized] if defined?(Type::Value)),
4
+ *([Enum::EnumType] if defined?(Enum::EnumType)),
5
+ ].each do |s|
6
+ s.class_eval do
7
+ if !method_defined?(:deserialize) && method_defined?(:type_cast_from_database)
8
+ # deserialize was changed to type_cast_from_database in Rails 5
9
+ alias_method :deserialize, :type_cast_from_database
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module PluckAll
3
- VERSION = '2.0.1'
3
+ VERSION = '2.2.1'
4
4
  end
@@ -4,34 +4,40 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'pluck_all/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "pluck_all"
7
+ spec.name = 'pluck_all'
8
8
  spec.version = PluckAll::VERSION
9
- spec.authors = ["khiav reoy"]
10
- spec.email = ["mrtmrt15xn@yahoo.com.tw"]
9
+ spec.authors = ['khiav reoy']
10
+ spec.email = ['mrtmrt15xn@yahoo.com.tw']
11
11
 
12
- spec.summary = %q{Pluck multiple columns/attributes and return array of hashes. Support Rails 3, 4, 5.}
13
- spec.description = %q{Pluck multiple columns/attributes and return array of hashes. Support Rails 3, 4, 5. 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 in the future will break this.}
14
- spec.homepage = "https://github.com/khiav223577/pluck_all"
15
- spec.license = "MIT"
12
+ spec.summary = 'Pluck multiple columns/attributes and return array of hashes. Support Rails 3, 4, 5.'
13
+ spec.description = 'Pluck multiple columns/attributes and return array of hashes. Support Rails 3, 4, 5. 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 in the future will break this.'
14
+ spec.homepage = 'https://github.com/khiav223577/pluck_all'
15
+ spec.license = 'MIT'
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
18
  # delete this section to allow pushing this gem to any host.
19
- #if spec.respond_to?(:metadata)
19
+ # if spec.respond_to?(:metadata)
20
20
  # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
- #else
21
+ # else
22
22
  # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
- #end
23
+ # end
24
24
 
25
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
- spec.bindir = "exe"
27
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
- spec.require_paths = ["lib"]
25
+ spec.files = `git ls-files -z`.split("\x0").reject{|f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = 'exe'
27
+ spec.executables = spec.files.grep(%r{^exe/}){|f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+ spec.metadata = {
30
+ 'homepage_uri' => 'https://github.com/khiav223577/pluck_all',
31
+ 'changelog_uri' => 'https://github.com/khiav223577/pluck_all/blob/master/CHANGELOG.md',
32
+ 'source_code_uri' => 'https://github.com/khiav223577/pluck_all',
33
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/pluck_all',
34
+ 'bug_tracker_uri' => 'https://github.com/khiav223577/pluck_all/issues',
35
+ }
29
36
 
30
- spec.add_development_dependency "bundler", "~> 1.11"
31
- spec.add_development_dependency "rake", "~> 12.0"
32
- spec.add_development_dependency "sqlite3", "~> 1.3"
33
- spec.add_development_dependency "minitest", "~> 5.0"
34
-
35
- spec.add_dependency "activerecord", ">= 3"
37
+ spec.add_dependency 'activesupport', '>= 3.0.0'
38
+ spec.add_dependency 'rails_compatibility', '>= 0.0.2'
36
39
 
40
+ spec.add_development_dependency 'bundler', '>= 1.17', '< 3.x'
41
+ spec.add_development_dependency 'rake', '~> 12.0'
42
+ spec.add_development_dependency 'minitest', '~> 5.0'
37
43
  end
metadata CHANGED
@@ -1,85 +1,91 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pluck_all
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - khiav reoy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-27 00:00:00.000000000 Z
11
+ date: 2020-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
20
- type: :development
19
+ version: 3.0.0
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: 3.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: rails_compatibility
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '12.0'
34
- type: :development
33
+ version: 0.0.2
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '12.0'
40
+ version: 0.0.2
41
41
  - !ruby/object:Gem::Dependency
42
- name: sqlite3
42
+ name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '1.3'
47
+ version: '1.17'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: 3.x
48
51
  type: :development
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
- - - "~>"
55
+ - - ">="
53
56
  - !ruby/object:Gem::Version
54
- version: '1.3'
57
+ version: '1.17'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: 3.x
55
61
  - !ruby/object:Gem::Dependency
56
- name: minitest
62
+ name: rake
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '5.0'
67
+ version: '12.0'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
72
  - - "~>"
67
73
  - !ruby/object:Gem::Version
68
- version: '5.0'
74
+ version: '12.0'
69
75
  - !ruby/object:Gem::Dependency
70
- name: activerecord
76
+ name: minitest
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
- - - ">="
79
+ - - "~>"
74
80
  - !ruby/object:Gem::Version
75
- version: '3'
76
- type: :runtime
81
+ version: '5.0'
82
+ type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
85
  requirements:
80
- - - ">="
86
+ - - "~>"
81
87
  - !ruby/object:Gem::Version
82
- version: '3'
88
+ version: '5.0'
83
89
  description: Pluck multiple columns/attributes and return array of hashes. Support
84
90
  Rails 3, 4, 5. If you have a Rails 3 project, and want to pluck not only one column,
85
91
  feel free to use this gem and no need to worry about upgrading to Rails 4, 5 in
@@ -91,6 +97,7 @@ extensions: []
91
97
  extra_rdoc_files: []
92
98
  files:
93
99
  - ".gitignore"
100
+ - ".rubocop.yml"
94
101
  - ".travis.yml"
95
102
  - CHANGELOG.md
96
103
  - CODE_OF_CONDUCT.md
@@ -99,20 +106,32 @@ files:
99
106
  - Rakefile
100
107
  - bin/console
101
108
  - bin/setup
102
- - gemfiles/3.2.gemfile
103
- - gemfiles/4.2.gemfile
104
- - gemfiles/5.0.gemfile
105
- - gemfiles/5.1.gemfile
106
- - gemfiles/5.2.gemfile
107
- - gemfiles/no_mongoid.gemfile
109
+ - gemfiles/active_record_32.gemfile
110
+ - gemfiles/active_record_42.gemfile
111
+ - gemfiles/active_record_50.gemfile
112
+ - gemfiles/active_record_51.gemfile
113
+ - gemfiles/active_record_52.gemfile
114
+ - gemfiles/active_record_60.gemfile
115
+ - gemfiles/active_record_61.gemfile
116
+ - gemfiles/mongoid_54.gemfile
117
+ - gemfiles/mongoid_64.gemfile
118
+ - gemfiles/mongoid_70.gemfile
108
119
  - lib/pluck_all.rb
109
- - lib/pluck_all/mongoid_pluck_all.rb
120
+ - lib/pluck_all/hooks.rb
121
+ - lib/pluck_all/models/active_record_extension.rb
122
+ - lib/pluck_all/models/mongoid_extension.rb
123
+ - lib/pluck_all/models/patches/deserialize.rb
110
124
  - lib/pluck_all/version.rb
111
125
  - pluck_all.gemspec
112
126
  homepage: https://github.com/khiav223577/pluck_all
113
127
  licenses:
114
128
  - MIT
115
- metadata: {}
129
+ metadata:
130
+ homepage_uri: https://github.com/khiav223577/pluck_all
131
+ changelog_uri: https://github.com/khiav223577/pluck_all/blob/master/CHANGELOG.md
132
+ source_code_uri: https://github.com/khiav223577/pluck_all
133
+ documentation_uri: https://www.rubydoc.info/gems/pluck_all
134
+ bug_tracker_uri: https://github.com/khiav223577/pluck_all/issues
116
135
  post_install_message:
117
136
  rdoc_options: []
118
137
  require_paths:
@@ -128,8 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
147
  - !ruby/object:Gem::Version
129
148
  version: '0'
130
149
  requirements: []
131
- rubyforge_project:
132
- rubygems_version: 2.7.6
150
+ rubygems_version: 3.0.3
133
151
  signing_key:
134
152
  specification_version: 4
135
153
  summary: Pluck multiple columns/attributes and return array of hashes. Support Rails