relation_to_struct 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +7 -0
- data/lib/relation_to_struct/active_record_relation_extension.rb +17 -0
- data/lib/relation_to_struct/version.rb +3 -0
- data/lib/relation_to_struct.rb +5 -0
- data/relation_to_struct.gemspec +30 -0
- data/spec/active_record_helper/economic_school.rb +3 -0
- data/spec/active_record_helper/economist.rb +3 -0
- data/spec/active_record_helper/schema.rb +12 -0
- data/spec/active_record_helper/setup.rb +33 -0
- data/spec/relation_to_struct_spec.rb +73 -0
- data/spec/spec_helper.rb +6 -0
- metadata +178 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: da24825b1afe7727be14670b9c455cb3e37787e8
|
4
|
+
data.tar.gz: 45d4ee2f132f955835ef6ccd06b313df2e063fd8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 37ec70d13d54eff799e4a0f270c2ed940323b014a029a9c3c28c1a9034190e773b9495cef5d6f097d5c00319daf6b255c55a2dc9a42a9e573930cdf7443763ba
|
7
|
+
data.tar.gz: a8b3b83a0460f846dca55d202aae7735db3fd16f3fe5ba58e2288bcdba21a2adc03d6086741e9246df774ee24d807dfe1199c7a4e8ad861efb26c98f9456c834
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 James Coleman
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# RelationToStruct
|
2
|
+
|
3
|
+
When one needs to use ActiveRecord to fetch specific values (whether subset columns of a model or arbitrary calculated columns), it's desirable to avoid the overhead of model instances and any associated callbacks.
|
4
|
+
|
5
|
+
ActiveRecord::Relation#pluck solves a similar problem but returns tuples; I wanted to be able to return Ruby structs to benefit from named instance methods.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'relation_to_struct'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install relation_to_struct
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it ( https://github.com/[my-github-username]/relation_to_struct/fork )
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module RelationToStruct::ActiveRecordRelationExtension
|
2
|
+
extend ::ActiveSupport::Concern
|
3
|
+
|
4
|
+
def to_structs(struct_class)
|
5
|
+
raise '' unless self.select_values.present?
|
6
|
+
|
7
|
+
relation = spawn
|
8
|
+
result = klass.connection.select_all(relation.arel, nil, relation.arel.bind_values + bind_values)
|
9
|
+
result.cast_values(klass.column_types)
|
10
|
+
|
11
|
+
result.cast_values(klass.column_types).map do |tuple|
|
12
|
+
struct_class.new(*tuple)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
::ActiveRecord::Relation.send(:include, RelationToStruct::ActiveRecordRelationExtension)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'relation_to_struct/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "relation_to_struct"
|
8
|
+
spec.version = RelationToStruct::VERSION
|
9
|
+
spec.authors = ["James Coleman"]
|
10
|
+
spec.email = ["jtc331@gmail.com"]
|
11
|
+
spec.summary = %q{Return struct results from ActiveRecord relation queries}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "sqlite3", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
25
|
+
spec.add_development_dependency "pry-byebug"
|
26
|
+
spec.add_development_dependency "pg"
|
27
|
+
|
28
|
+
spec.add_dependency "activerecord", "~> 4.0"
|
29
|
+
spec.add_dependency "activesupport", "~> 4.0"
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
ActiveRecord::Base.configurations = {
|
2
|
+
"postgresql" => {
|
3
|
+
"adapter" => 'postgresql',
|
4
|
+
"host" => 'localhost',
|
5
|
+
"database" => 'relation_to_struct_tests',
|
6
|
+
"encoding" => 'utf8',
|
7
|
+
"username" => 'jcoleman',
|
8
|
+
},
|
9
|
+
"sqlite" => {
|
10
|
+
"adapter" => "sqlite3",
|
11
|
+
"database" => ":memory:",
|
12
|
+
},
|
13
|
+
}
|
14
|
+
|
15
|
+
env = ENV['DATABASE'] ||= 'sqlite'
|
16
|
+
case env
|
17
|
+
when 'postgresql'
|
18
|
+
ActiveRecord::Tasks::DatabaseTasks.instance_variable_set('@env', env)
|
19
|
+
config = ActiveRecord::Base.configurations[env]
|
20
|
+
|
21
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current
|
22
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current
|
23
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:ruby, File.expand_path('../schema.rb', __FILE__))
|
24
|
+
ActiveRecord::Base.establish_connection(env)
|
25
|
+
when 'sqlite'
|
26
|
+
ActiveRecord::Base.establish_connection(env)
|
27
|
+
require_relative 'schema'
|
28
|
+
else
|
29
|
+
raise ArgumentError, 'Unrecognized ENV["DATABASE"] argument.'
|
30
|
+
end
|
31
|
+
|
32
|
+
require_relative 'economic_school'
|
33
|
+
require_relative 'economist'
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RelationToStruct do
|
4
|
+
before(:each) do
|
5
|
+
Economist.delete_all
|
6
|
+
EconomicSchool.delete_all
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'has a version number' do
|
10
|
+
expect(RelationToStruct::VERSION).not_to be nil
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'relation' do
|
14
|
+
it 'should respond to :to_structs' do
|
15
|
+
expect(Economist.all.respond_to?(:to_structs)).to eq(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should respond to :to_structs' do
|
19
|
+
pending 'next version'
|
20
|
+
end
|
21
|
+
|
22
|
+
it '#to_structs should raise an error when the relation has no select_values' do
|
23
|
+
expect do
|
24
|
+
Economist.all.to_structs(Struct.new(:test_struct))
|
25
|
+
end.to raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it '#to_structs should return an empty array when no results are returned' do
|
29
|
+
expect(Economist.where('1 = 0').select(:id).to_structs(Struct.new(:test_struct))).to eq([])
|
30
|
+
end
|
31
|
+
|
32
|
+
it '#to_structs should return an array with struct instances' do
|
33
|
+
hayek = Economist.create!(name: 'F.A. Hayek')
|
34
|
+
id_struct = Struct.new(:id)
|
35
|
+
expect(Economist.all.select(:id).to_structs(id_struct)).to eq([id_struct.new(hayek.id)])
|
36
|
+
end
|
37
|
+
|
38
|
+
it '#to_structs should handle joined elements properly' do
|
39
|
+
austrian = EconomicSchool.create!(name: 'Austrian Economics')
|
40
|
+
hayek = Economist.create!(name: 'F.A. Hayek', economic_school: austrian)
|
41
|
+
test_struct = Struct.new(:name, :school)
|
42
|
+
expect(
|
43
|
+
Economist
|
44
|
+
.joins(:economic_school)
|
45
|
+
.select('economists.name', 'economic_schools.name')
|
46
|
+
.to_structs(test_struct)
|
47
|
+
).to eq([test_struct.new(hayek.name, austrian.name)])
|
48
|
+
end
|
49
|
+
|
50
|
+
it '#to_structs should properly cast values from arbitrary calculated columns' do
|
51
|
+
hayek = Economist.create!(name: 'F.A. Hayek')
|
52
|
+
scope = Economist.all
|
53
|
+
pluck_results = scope.pluck("date('now')")
|
54
|
+
pluck_column_klass = pluck_results.first.class
|
55
|
+
|
56
|
+
date_struct = Struct.new(:date)
|
57
|
+
struct_scope = scope.select("date('now')")
|
58
|
+
structs_results = struct_scope.to_structs(date_struct)
|
59
|
+
struct_column_klass = structs_results.first.date.class
|
60
|
+
expect(pluck_column_klass).to eq(struct_column_klass)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'non-model specific querying' do
|
65
|
+
it 'should allow querying from ActiveRecord' do
|
66
|
+
pending 'next version'
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should allow using find_by_sql directly' do
|
70
|
+
pending 'next version'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: relation_to_struct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Coleman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pg
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activerecord
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '4.0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '4.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: activesupport
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4.0'
|
125
|
+
description: ''
|
126
|
+
email:
|
127
|
+
- jtc331@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- Gemfile
|
135
|
+
- LICENSE.txt
|
136
|
+
- README.md
|
137
|
+
- Rakefile
|
138
|
+
- lib/relation_to_struct.rb
|
139
|
+
- lib/relation_to_struct/active_record_relation_extension.rb
|
140
|
+
- lib/relation_to_struct/version.rb
|
141
|
+
- relation_to_struct.gemspec
|
142
|
+
- spec/active_record_helper/economic_school.rb
|
143
|
+
- spec/active_record_helper/economist.rb
|
144
|
+
- spec/active_record_helper/schema.rb
|
145
|
+
- spec/active_record_helper/setup.rb
|
146
|
+
- spec/relation_to_struct_spec.rb
|
147
|
+
- spec/spec_helper.rb
|
148
|
+
homepage: ''
|
149
|
+
licenses:
|
150
|
+
- MIT
|
151
|
+
metadata: {}
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubyforge_project:
|
168
|
+
rubygems_version: 2.4.5
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: Return struct results from ActiveRecord relation queries
|
172
|
+
test_files:
|
173
|
+
- spec/active_record_helper/economic_school.rb
|
174
|
+
- spec/active_record_helper/economist.rb
|
175
|
+
- spec/active_record_helper/schema.rb
|
176
|
+
- spec/active_record_helper/setup.rb
|
177
|
+
- spec/relation_to_struct_spec.rb
|
178
|
+
- spec/spec_helper.rb
|