postgres_ext-serializers 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc2786f412177b97b379240e2c651b3af66b4529
4
+ data.tar.gz: a593579437d26066cdc7ba5afce361447cd27bb5
5
+ SHA512:
6
+ metadata.gz: dedcaefb8fa0a5228cd7221381550621eed39c63c7c031e88483e901ccf57aa587c4a79ffc4cc0f8a0420a15b7c42ebb8fe3c31cf1623a9bb2a8a94c3a81c4ac
7
+ data.tar.gz: c7ef64efe1d96a3aa2171560b6d775b7706fc736c0d1840bd5ba1d1e56330bb973b996cc2d43e17082e1d4196ab9ff4b0fbbdac99f9174394a307a684c220040
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ bin/
19
+ .env
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in postgres_ext-serializers.gemspec
4
+ gemspec
5
+
6
+ unless ENV['CI'] || RUBY_PLATFORM =~ /java/
7
+ gem 'byebug'
8
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Dan McClain
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.
@@ -0,0 +1,82 @@
1
+ # PostgresExt-Serializers
2
+
3
+
4
+ [![Build
5
+ Status](https://secure.travis-ci.org/dockyard/postgres_ext-serializers.png?branch=master)](http://travis-ci.org/dockyard/postgres_ext-serializers)
6
+ [![Code
7
+ Climate](https://codeclimate.com/github/dockyard/postgres_ext-serializers.png)](https://codeclimate.com/github/dockyard/postgres_ext-serializers)
8
+ [![Gem
9
+ Version](https://badge.fury.io/rb/postgres_ext-serializers.png)](http://badge.fury.io/rb/postgres_ext-serializers)
10
+
11
+ ## Looking for help? ##
12
+
13
+ If it is a bug [please open an issue on
14
+ Github](https://github.com/dockyard/postgres_ext-serializers/issues). If you need
15
+ help using the gem please ask the question on
16
+ [Stack Overflow](http://stackoverflow.com). Be sure to tag the
17
+ question with `DockYard` so we can find it.
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ gem 'postgres_ext-serializers'
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install postgres_ext-serializers
32
+
33
+ ## Usage
34
+
35
+ Just `require 'postgres_ext/serializers'` and use
36
+ ActiveModel::Serializers as you normally would!
37
+ Postgres\_ext-serializers will take over anytime you try to serialize an
38
+ ActiveRecord::Relation.
39
+
40
+ ### Methods in Serializers and Models
41
+
42
+ If you are using methods to compute properties for your JSON responses
43
+ in your models or serializers, postgres\_ext-serializers will try to
44
+ discover a SQL version of this call by looking for a class method with
45
+ the same name and the prefex `__sql`. Here's an example:
46
+
47
+ ```ruby
48
+ class MySerializer < ActiveModel::Serializer
49
+ def full_name
50
+ "#{object.first_name} #{object.last_name}"
51
+ end
52
+
53
+ def self.full_name__sql(scope)
54
+ 'first_name || ' ' || last_name'
55
+ end
56
+ end
57
+ ```
58
+
59
+ The scope is passed to methods in a serializer, while there are no
60
+ arguments passed to `__sql` methods in a model. You will not have access
61
+ to the `current_user` alias of `scope`, but the scope passed in will be
62
+ the same object. Right now, this string is used as a SQL literal, so be
63
+ sure to *not* use untrusted values in the return value. This feature may
64
+ change before the 1.0 release, if a cleaner implementation is found.
65
+
66
+ ## Developing
67
+
68
+ To work on postgres\_ext locally, follow these steps:
69
+
70
+ 1. Run `bundle install`, this will install all the development
71
+ dependencies
72
+ 2. Run `rake setup`, this will set up the `.env` file necessary to run
73
+ the tests and set up the database
74
+ 3. Run `rake db:create`, this will create the test database
75
+ 4. Run `rake db:migrate`, this will set up the database tables required
76
+ by the test
77
+
78
+ ## Authors
79
+
80
+ Dan McClain [twitter](http://twitter.com/_danmcclain)
81
+ [github](http://github.com/danmcclain)
82
+
@@ -0,0 +1,88 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'lib'
6
+ t.libs << 'test'
7
+ t.pattern = 'test/**/*_test.rb'
8
+ t.verbose = false
9
+ end
10
+
11
+ task :default => :test
12
+
13
+ task :setup do
14
+ if File.exist?('.env')
15
+ puts 'This will overwrite your existing .env file'
16
+ end
17
+ print 'Enter your database name: [postgres_ext_serializers_test] '
18
+ db_name = STDIN.gets.chomp
19
+ print 'Enter your database user: [] '
20
+ db_user = STDIN.gets.chomp
21
+ print 'Enter your database password: [] '
22
+ db_password = STDIN.gets.chomp
23
+ print 'Enter your database server: [localhost] '
24
+ db_server = STDIN.gets.chomp
25
+
26
+ db_name = 'postgres_ext_test' if db_name.empty?
27
+ db_password = ":#{db_password}" unless db_password.empty?
28
+ db_server = 'localhost' if db_server.empty?
29
+
30
+ db_server = "@#{db_server}" unless db_user.empty?
31
+
32
+ env_path = File.expand_path('./.env')
33
+ File.open(env_path, 'w') do |file|
34
+ file.puts "DATABASE_NAME=#{db_name}"
35
+ file.puts "DATABASE_URL=\"postgres://#{db_user}#{db_password}#{db_server}/#{db_name}\""
36
+ end
37
+
38
+ puts '.env file saved'
39
+ end
40
+
41
+ namespace :db do
42
+ task :load_db_settings do
43
+ require 'active_record'
44
+ unless ENV['DATABASE_URL']
45
+ require 'dotenv'
46
+ Dotenv.load
47
+ end
48
+ end
49
+
50
+ task :psql => :load_db_settings do
51
+ exec "psql #{ENV['DATABASE_NAME']}"
52
+ end
53
+
54
+ task :drop => :load_db_settings do
55
+ %x{ dropdb #{ENV['DATABASE_NAME']} }
56
+ end
57
+
58
+ task :create => :load_db_settings do
59
+ %x{ createdb #{ENV['DATABASE_NAME']} }
60
+ end
61
+
62
+ task :migrate => :load_db_settings do
63
+ ActiveRecord::Base.establish_connection
64
+
65
+ ActiveRecord::Base.connection.create_table :people, force: true do |t|
66
+ t.string "first_name"
67
+ t.string "last_name"
68
+ t.datetime "created_at"
69
+ t.datetime "updated_at"
70
+ end
71
+
72
+ ActiveRecord::Base.connection.create_table :notes, force: true do |t|
73
+ t.string "name"
74
+ t.string "content"
75
+ t.datetime "created_at"
76
+ t.datetime "updated_at"
77
+ end
78
+
79
+ ActiveRecord::Base.connection.create_table :tags, force: true do |t|
80
+ t.integer "note_id"
81
+ t.string "name"
82
+ t.datetime "created_at"
83
+ t.datetime "updated_at"
84
+ end
85
+
86
+ puts 'Database migrated'
87
+ end
88
+ end
@@ -0,0 +1,12 @@
1
+ require 'postgres_ext'
2
+ require 'postgres_ext/serializers/version'
3
+
4
+ module PostgresExt
5
+ module Serializers
6
+ end
7
+ end
8
+
9
+ require 'postgres_ext/serializers/active_model'
10
+ require 'active_model_serializers'
11
+
12
+ ActiveModel::ArraySerializer.send :prepend, PostgresExt::Serializers::ActiveModel::ArraySerializer
@@ -0,0 +1,6 @@
1
+ module PostgresExt::Serializers
2
+ module ActiveModel
3
+ end
4
+ end
5
+
6
+ require 'postgres_ext/serializers/active_model/array_serializer'
@@ -0,0 +1,194 @@
1
+ module PostgresExt::Serializers::ActiveModel
2
+ module ArraySerializer
3
+ def self.prepended(base)
4
+ base.send :include, IncludeMethods
5
+ end
6
+
7
+ module IncludeMethods
8
+ def to_json(*)
9
+ if ActiveRecord::Relation === object
10
+ _postgres_serializable_array
11
+ else
12
+ super
13
+ end
14
+ end
15
+ end
16
+
17
+ def initialize(*)
18
+ super
19
+ @_ctes = []
20
+ @_results_tables = []
21
+ @_embedded = []
22
+ end
23
+
24
+ private
25
+
26
+ def _postgres_serializable_array
27
+ _include_relation_in_root(object)
28
+
29
+ jsons_select_manager = _results_table_arel
30
+ jsons_select_manager.with @_ctes
31
+
32
+ object.klass.connection.select_value _visitor.accept(jsons_select_manager)
33
+ end
34
+
35
+ def _include_relation_in_root(relation, foreign_key_column = nil, constraining_table = nil)
36
+ relation_query = relation.dup
37
+ relation_query_arel = relation_query.arel_table
38
+ @_embedded << relation.table_name
39
+
40
+ klass = ActiveRecord::Relation === relation ? relation.klass : relation
41
+ serializer_class = _serializer_class(klass)
42
+ _serializer = serializer_class.new klass.new, options
43
+
44
+ attributes = serializer_class._attributes
45
+ attributes.each do |name, key|
46
+ if name.to_s == key.to_s
47
+ if serializer_class.respond_to? "#{name}__sql"
48
+ relation_query = relation_query.select Arel::Nodes::As.new Arel.sql(serializer_class.send("#{name}__sql", options[:scope])), Arel.sql(name.to_s)
49
+ elsif klass.respond_to? "#{name}__sql"
50
+ relation_query = relation_query.select Arel::Nodes::As.new Arel.sql(klass.send("#{name}__sql")), Arel.sql(name.to_s)
51
+ else
52
+ relation_query = relation_query.select(relation_query_arel[name])
53
+ end
54
+ end
55
+ end
56
+
57
+ if foreign_key_column && constraining_table
58
+ relation_query = relation_query.where(relation_query_arel[foreign_key_column].in(constraining_table.project(constraining_table[:id])))
59
+ end
60
+
61
+ associations = serializer_class._associations
62
+ association_sql_tables = []
63
+ ids_table_name = nil
64
+ id_query = nil
65
+ unless associations.empty?
66
+ ids_table_name = "#{relation.table_name}_ids"
67
+ ids_table_arel = Arel::Table.new ids_table_name
68
+ id_query = relation.dup.select(:id)
69
+ if foreign_key_column && constraining_table
70
+ id_query.where!(relation_query_arel[foreign_key_column].in(constraining_table.project(constraining_table[:id])))
71
+ end
72
+ end
73
+
74
+ associations.each do |key, association_class|
75
+ association = association_class.new key, _serializer, options
76
+
77
+ association_reflection = klass.reflect_on_association(key)
78
+ if association.embed_ids?
79
+ if association_reflection.macro == :has_many
80
+ unless @_ctes.find { |as| as.left == ids_table_name }
81
+ @_ctes << _postgres_cte_as(ids_table_name, "(#{id_query.to_sql})")
82
+ end
83
+ association_sql_tables << _process_has_many_relation(key, association_reflection, relation_query, ids_table_arel)
84
+ else
85
+ relation_query = relation_query.select(relation_query_arel["#{key}_id"])
86
+ end
87
+ end
88
+
89
+ if association.embed_in_root? && !@_embedded.member?(key.to_s)
90
+ _include_relation_in_root(association_reflection.klass,association_reflection.foreign_key,ids_table_arel)
91
+ end
92
+ end
93
+ arel = relation_query.arel.dup
94
+
95
+ association_sql_tables.each do |assoc_hash|
96
+ assoc_table = Arel::Table.new assoc_hash[:table]
97
+ arel.join(assoc_table, Arel::Nodes::OuterJoin).on(relation_query_arel[:id].eq(assoc_table[assoc_hash[:foreign_key]]))
98
+ arel.project _coalesce_arrays(assoc_table[assoc_hash[:ids_column]], assoc_hash[:ids_column])
99
+ end
100
+
101
+ _arel_to_json_array_arel(arel, relation_query.table_name)
102
+ end
103
+
104
+ def _process_has_many_relation(key, association_reflection, relation_query, ids_table_arel)
105
+ association_class = association_reflection.klass
106
+ association_arel_table = association_class.arel_table
107
+ association_query = association_class.group association_arel_table[association_reflection.foreign_key]
108
+ association_query = association_query.select(association_arel_table[association_reflection.foreign_key])
109
+ id_column_name = "#{key.to_s.singularize}_ids"
110
+ cte_name = "#{id_column_name}_by_#{relation_query.table_name}"
111
+ association_query = association_query.select(_array_agg(association_arel_table[:id], id_column_name))
112
+ association_query = association_query.having(association_arel_table[association_reflection.foreign_key].in(ids_table_arel.project(ids_table_arel[:id])))
113
+ @_ctes << _postgres_cte_as(cte_name, "(#{association_query.to_sql})")
114
+ { table: cte_name, ids_column: id_column_name, foreign_key: association_reflection.foreign_key }
115
+ end
116
+
117
+ def _visitor
118
+ @_visitior ||= object.klass.connection.visitor
119
+ end
120
+
121
+ def _serializer_class(klass)
122
+ klass.active_model_serializer
123
+ end
124
+
125
+ def _coalesce_arrays(column, aliaz = nil)
126
+ _postgres_function_node 'coalesce', [column, Arel.sql("'{}'::int[]")], aliaz
127
+ end
128
+
129
+ def _results_table_arel
130
+ first = @_results_tables.shift
131
+ first_table = Arel::Table.new first[:table]
132
+ jsons_select = first_table.project first_table[first[:column]]
133
+
134
+ @_results_tables.each do |table_info|
135
+ table = Arel::Table.new table_info[:table]
136
+ jsons_select = jsons_select.project table[table_info[:column]]
137
+ jsons_select.join(table).on(first_table[:match].eq(table[:match]))
138
+ end
139
+
140
+ @_ctes << _postgres_cte_as('jsons', _visitor.accept(jsons_select))
141
+
142
+ jsons_table = Arel::Table.new 'jsons'
143
+ jsons_row_to_json = _row_to_json jsons_table.name
144
+ jsons_table.project jsons_row_to_json
145
+ end
146
+
147
+ def _arel_to_json_array_arel(arel, name)
148
+ json_table = Arel::Table.new "#{name}_attributes_filter"
149
+ json_select_manager = json_table.project _results_as_json_array(json_table.name, name)
150
+ json_select_manager.project Arel::Nodes::As.new Arel.sql('1'), Arel.sql('match')
151
+
152
+ @_ctes << _postgres_cte_as(json_table.name, _visitor.accept(arel))
153
+ @_ctes << _postgres_cte_as("#{name}_as_json_array", _visitor.accept(json_select_manager))
154
+ @_results_tables << { table: "#{name}_as_json_array", column: name }
155
+ end
156
+
157
+ def _relation_to_json_array_arel(relation)
158
+ json_table = Arel::Table.new "#{relation.table_name}_json"
159
+ json_select_manager = json_table.project _results_as_json_array(json_table.name, relation.table_name)
160
+
161
+ @_ctes << _postgres_cte_as(json_table.name, "(#{relation.to_sql})")
162
+
163
+ json_select_manager
164
+ end
165
+
166
+ def _row_to_json(table_name, aliaz = nil)
167
+ _postgres_function_node 'row_to_json', [Arel.sql(table_name)], aliaz
168
+ end
169
+
170
+ def _postgres_cte_as(name, sql_string)
171
+ Arel::Nodes::As.new Arel.sql(name), Arel.sql(sql_string)
172
+ end
173
+
174
+ def _results_as_json_array(table_name, aliaz = nil)
175
+ row_as_json = _row_to_json table_name
176
+ array_of_json = _postgres_function_node 'array_agg', [row_as_json]
177
+ _postgres_function_node 'array_to_json', [array_of_json], aliaz
178
+ end
179
+
180
+ def _array_agg(column, aliaz = nil)
181
+ _postgres_function_node 'array_agg', [column], aliaz
182
+ end
183
+
184
+ def _array_agg_as_json(column, aliaz = nil)
185
+ array_agg = _array_agg [column]
186
+ _postgres_function_node 'array_to_json', [array_agg], aliaz
187
+ end
188
+
189
+ def _postgres_function_node(name, values, aliaz = nil)
190
+ Arel::Nodes::NamedFunction.new(name, values, aliaz)
191
+ end
192
+ end
193
+ end
194
+
@@ -0,0 +1,5 @@
1
+ module PostgresExt
2
+ module Serializers
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'postgres_ext/serializers/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "postgres_ext-serializers"
8
+ spec.version = PostgresExt::Serializers::VERSION
9
+ spec.authors = ["Dan McClain"]
10
+ spec.email = ["git@danmcclain.net"]
11
+ spec.summary = %q{Harness the power of PostgreSQL when crafting JSON reponses }
12
+ spec.description = %q{}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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_runtime_dependency 'postgres_ext', '~> 2.1.0'
22
+ spec.add_runtime_dependency 'active_model_serializers'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'actionpack', '~> 4.0.0'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'minitest'
28
+ spec.add_development_dependency 'm'
29
+ spec.add_development_dependency 'bourne', '~> 1.3.0'
30
+ spec.add_development_dependency 'database_cleaner'
31
+ spec.add_development_dependency 'dotenv'
32
+ if RUBY_PLATFORM =~ /java/
33
+ spec.add_development_dependency 'activerecord-jdbcpostgresql-adapter', '1.3.0.beta2'
34
+ else
35
+ spec.add_development_dependency 'pg', '~> 0.13.2'
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+
4
+ describe 'ArraySerializer patch' do
5
+ let(:json_data) { ActiveModel::Serializer.build_json(controller, relation, {}).to_json }
6
+
7
+ context 'computed value methods' do
8
+ let(:relation) { Person.all }
9
+ let(:controller) { PeopleController.new }
10
+ let(:person) { Person.create first_name: 'Test', last_name: 'User' }
11
+
12
+ it 'generates the proper json output for the serializer' do
13
+ json_expected = %{{"people":[{"id":#{person.id},"full_name":"Test User","attendance_name":"User, Test"}]}}
14
+ json_data.must_equal json_expected
15
+ end
16
+
17
+ it 'passes scope to the serializer method' do
18
+ controller.stubs(:current_user).returns({ admin: true })
19
+
20
+ json_expected = %{{"people":[{"id":#{person.id},"full_name":"Test User","attendance_name":"ADMIN User, Test"}]}}
21
+ json_data.must_equal json_expected
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,52 @@
1
+
2
+ describe 'ArraySerializer patch' do
3
+ let(:json_data) { ActiveModel::Serializer.build_json(controller, relation, {}).to_json }
4
+
5
+ context 'no where clause on root relation' do
6
+ let(:relation) { Note.all }
7
+ let(:controller) { NotesController.new }
8
+
9
+ before do
10
+ note_1 = Note.create name: 'test', content: 'dummy content'
11
+ note_2 = Note.create name: 'test 2', content: 'dummy content'
12
+
13
+ tag = Tag.create name: 'tag 1', note_id: note_1.id
14
+ Tag.create name: 'tag 2'
15
+ @json_expected = "{\"tags\":[{\"id\":#{tag.id},\"name\":\"tag 1\",\"note_id\":#{note_1.id}}],\"notes\":[{\"id\":#{note_1.id},\"content\":\"dummy content\",\"name\":\"test\",\"tag_ids\":[#{tag.id}]},{\"id\":#{note_2.id},\"content\":\"dummy content\",\"name\":\"test 2\",\"tag_ids\":[]}]}"
16
+ end
17
+
18
+ it 'generates the proper json output for the serializer' do
19
+ json_data.must_equal @json_expected
20
+ end
21
+
22
+ it 'does not instantiate ruby objects for relations' do
23
+ relation.stubs(:to_a).returns([])
24
+ json_data
25
+ assert_received(relation, :to_a) { |expect| expect.never}
26
+ end
27
+ end
28
+
29
+ context 'where clause on root relation' do
30
+ let(:relation) { Note.where(name: 'test') }
31
+ let(:controller) { NotesController.new }
32
+
33
+ before do
34
+ note_1 = Note.create name: 'test', content: 'dummy content'
35
+ note_2 = Note.create name: 'test 2', content: 'dummy content'
36
+
37
+ tag = Tag.create name: 'tag 1', note_id: note_1.id
38
+ Tag.create name: 'tag 2', note_id: note_2.id
39
+ @json_expected = "{\"tags\":[{\"id\":#{tag.id},\"name\":\"tag 1\",\"note_id\":#{note_1.id}}],\"notes\":[{\"id\":#{note_1.id},\"content\":\"dummy content\",\"name\":\"test\",\"tag_ids\":[#{tag.id}]}]}"
40
+ end
41
+
42
+ it 'generates the proper json output for the serializer' do
43
+ json_data.must_equal @json_expected
44
+ end
45
+
46
+ it 'does not instantiate ruby objects for relations' do
47
+ relation.stubs(:to_a).returns([])
48
+ json_data
49
+ assert_received(relation, :to_a) { |expect| expect.never}
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,81 @@
1
+ require 'active_record'
2
+ require 'minitest/autorun'
3
+ require 'test/unit'
4
+ require 'mocha/setup'
5
+ require 'bourne'
6
+ require 'database_cleaner'
7
+ unless ENV['CI'] || RUBY_PLATFORM =~ /java/
8
+ require 'byebug'
9
+ end
10
+ require 'postgres_ext/serializers'
11
+
12
+ require 'dotenv'
13
+ Dotenv.load
14
+
15
+ ActiveRecord::Base.establish_connection
16
+
17
+ class TestController < ActionController::Base
18
+ def url_options
19
+ {}
20
+ end
21
+ end
22
+
23
+ class Person < ActiveRecord::Base
24
+ def self.full_name__sql
25
+ "first_name || ' ' || last_name"
26
+ end
27
+ end
28
+
29
+ class PeopleController < TestController; end
30
+
31
+ class PersonSerializer < ActiveModel::Serializer
32
+ attributes :id, :full_name, :attendance_name
33
+
34
+ def self.attendance_name__sql(scope)
35
+ if scope && scope[:admin]
36
+ "'ADMIN ' || last_name || ', ' || first_name"
37
+ else
38
+ "last_name || ', ' || first_name"
39
+ end
40
+ end
41
+ end
42
+
43
+ class Note < ActiveRecord::Base
44
+ has_many :tags
45
+ end
46
+
47
+ class NotesController < TestController; end
48
+
49
+ class NoteSerializer < ActiveModel::Serializer
50
+ attributes :id, :content, :name
51
+ has_many :tags
52
+ embed :ids, include: true
53
+ end
54
+
55
+ class Tag < ActiveRecord::Base
56
+ belongs_to :note
57
+ end
58
+
59
+
60
+
61
+ class TagSerializer < ActiveModel::Serializer
62
+ attributes :id, :name
63
+ embed :ids
64
+ has_one :note
65
+ end
66
+
67
+ DatabaseCleaner.strategy = :deletion
68
+
69
+ class MiniTest::Spec
70
+ class << self
71
+ alias :context :describe
72
+ end
73
+
74
+ before do
75
+ DatabaseCleaner.start
76
+ end
77
+
78
+ after do
79
+ DatabaseCleaner.clean
80
+ end
81
+ end
metadata ADDED
@@ -0,0 +1,214 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: postgres_ext-serializers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dan McClain
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: postgres_ext
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: active_model_serializers
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
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: actionpack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 4.0.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 4.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
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: minitest
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: m
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: bourne
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.3.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.3.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: database_cleaner
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: dotenv
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: pg
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.13.2
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.13.2
167
+ description: ''
168
+ email:
169
+ - git@danmcclain.net
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - ".gitignore"
175
+ - Gemfile
176
+ - LICENSE.txt
177
+ - README.md
178
+ - Rakefile
179
+ - lib/postgres_ext/serializers.rb
180
+ - lib/postgres_ext/serializers/active_model.rb
181
+ - lib/postgres_ext/serializers/active_model/array_serializer.rb
182
+ - lib/postgres_ext/serializers/version.rb
183
+ - postgres_ext-serializers.gemspec
184
+ - test/serializer_test.rb
185
+ - test/sideloading_test.rb
186
+ - test/test_helper.rb
187
+ homepage: ''
188
+ licenses:
189
+ - MIT
190
+ metadata: {}
191
+ post_install_message:
192
+ rdoc_options: []
193
+ require_paths:
194
+ - lib
195
+ required_ruby_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ requirements: []
206
+ rubyforge_project:
207
+ rubygems_version: 2.2.0
208
+ signing_key:
209
+ specification_version: 4
210
+ summary: Harness the power of PostgreSQL when crafting JSON reponses
211
+ test_files:
212
+ - test/serializer_test.rb
213
+ - test/sideloading_test.rb
214
+ - test/test_helper.rb