activerecord_base_without_table 0.1.0
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/MIT-LICENSE +20 -0
- data/Rakefile +27 -0
- data/lib/active_record/attributes_builder_without_table.rb +29 -0
- data/lib/active_record/base_without_table.rb +90 -0
- data/lib/active_record/connection_adapters/null_adapter.rb +14 -0
- data/lib/active_record/connection_adapters/null_schema_cache.rb +23 -0
- data/lib/activerecord_base_without_table.rb +1 -0
- data/lib/tasks/base_without_table_migration_harness_tasks.rake +4 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: be21cd5618a56030b694f04f7328e5e4b5f773806ee76a856723af5004609b7d
|
4
|
+
data.tar.gz: beba62e1fa11da71bb91c95e85fd858a7d564aa7a90b59f71fd4276529d42a0c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: be45034ab5e6ffc9bfd5ccbb3166327df61a2e2745a6da089078ecfe85fadf8cc2e4ecc3b17d09fbdd75af8c81037768fcc98a2f483f3664ebe44dc24a2ae4af
|
7
|
+
data.tar.gz: 1dbcb3a7ef8ff4eacd38fdc81c02b6e1a3e62fb34ff919e9bb37b425c1dd0af6b61c6cd70e00607c2f19fc522976a699fe01c72230bb4fc4f8ec7703d30eb28e
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 Ryan De Villa
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'ActiveRecord::BaseWithoutTable'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
Bundler::GemHelper.install_tasks
|
18
|
+
|
19
|
+
begin
|
20
|
+
require 'rspec/core/rake_task'
|
21
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
22
|
+
t.rspec_opts = "-rbyebug --format documentation"
|
23
|
+
end
|
24
|
+
rescue LoadError
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :spec
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This class exists to support the use of `find_by_sql` on BaseWithoutTable
|
4
|
+
# instances. It is highly aware of internal implementation details of
|
5
|
+
# ActiveRecord.
|
6
|
+
#
|
7
|
+
# It ensures that Attributes that have been decorated
|
8
|
+
# (e.g. with time zone conversion decorators) at class method evaluation
|
9
|
+
# time do not lose their decoration when BaseWithoutTable instances are
|
10
|
+
# brought to life via `#instantiate` (by way of `#find_by_sql`).
|
11
|
+
#
|
12
|
+
# This occurs when ActiveRecord needs to synthesize Attributes for
|
13
|
+
# `additional_types` that are not part of the record's schema, which may
|
14
|
+
# result from joining in columns from an associated relation in a raw SQL
|
15
|
+
# query.
|
16
|
+
#
|
17
|
+
# Since the NullSchemaCache declares that the record has no schema,
|
18
|
+
# all `additional_types` are in need of an Attribute to represent them.
|
19
|
+
# However, creating them would clobber the Attributes that were already
|
20
|
+
# constructed in the evaluation of the `BaseWithoutTable::column`
|
21
|
+
# class method, and remove the decoration that was applied to them at that
|
22
|
+
# time.
|
23
|
+
module ActiveRecord
|
24
|
+
class AttributesBuilderWithoutTable < SimpleDelegator
|
25
|
+
def build_from_database(values = {}, additional_types = {})
|
26
|
+
super(values, {})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_record/attributes_builder_without_table'
|
4
|
+
require 'active_record/connection_adapters/null_adapter'
|
5
|
+
require 'active_record/connection_adapters/null_schema_cache'
|
6
|
+
|
7
|
+
module ActiveRecord
|
8
|
+
# Get the power of ActiveRecord models, including validation, without having a
|
9
|
+
# table in the database.
|
10
|
+
#
|
11
|
+
# == Usage
|
12
|
+
#
|
13
|
+
# class Contact < ActiveRecord::BaseWithoutTable
|
14
|
+
# column :name, :text
|
15
|
+
# column :email_address, :text
|
16
|
+
# column :message, :text
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# validates_presence_of :name, :email_address, :string
|
20
|
+
#
|
21
|
+
# This model can be used just like a regular model based on a table, except it
|
22
|
+
# will never be saved to the database.
|
23
|
+
#
|
24
|
+
class BaseWithoutTable < Base
|
25
|
+
self.abstract_class = true
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def connection
|
29
|
+
ConnectionAdapters::NullAdapter.new(super)
|
30
|
+
end
|
31
|
+
|
32
|
+
def attributes_builder
|
33
|
+
AttributesBuilderWithoutTable.new(super)
|
34
|
+
end
|
35
|
+
|
36
|
+
def table_exists?
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def inherited(subclass)
|
41
|
+
subclass.define_singleton_method(:table_name) do
|
42
|
+
"activerecord_base_without_table_#{subclass.name}"
|
43
|
+
end
|
44
|
+
super(subclass)
|
45
|
+
end
|
46
|
+
|
47
|
+
def attribute_names
|
48
|
+
_default_attributes.keys.map(&:to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
def column(name, sql_type = nil, default = nil, null = true)
|
52
|
+
cast_type = lookup_attribute_type(sql_type)
|
53
|
+
decorated_type = attribute_type_decorations.apply(name, cast_type)
|
54
|
+
|
55
|
+
define_attribute(name.to_s, decorated_type, default: default)
|
56
|
+
end
|
57
|
+
|
58
|
+
def lookup_attribute_type(sql_type)
|
59
|
+
# This is an emulation of the Rails 4.1 runtime behaviour.
|
60
|
+
# Please consider rewriting once we move to Rails 5.1.
|
61
|
+
mapped_sql_type =
|
62
|
+
case sql_type
|
63
|
+
when :datetime
|
64
|
+
:date_time
|
65
|
+
when :datetime_point
|
66
|
+
:integer
|
67
|
+
when :enumerable
|
68
|
+
:value
|
69
|
+
else
|
70
|
+
sql_type
|
71
|
+
end.to_s.camelize
|
72
|
+
|
73
|
+
"::ActiveRecord::Type::#{mapped_sql_type}".constantize.new
|
74
|
+
end
|
75
|
+
|
76
|
+
def gettext_translation_for_attribute_name(attribute)
|
77
|
+
# `rake gettext:store_model_attributes` processes our BaseWithoutTable models, but we have our own rake task
|
78
|
+
# for that. Return right away if calling gettext_translation_for_attribute_name on BaseWithoutTable
|
79
|
+
return "BaseWithoutTable" if self == BaseWithoutTable
|
80
|
+
|
81
|
+
attribute = attribute.to_s
|
82
|
+
if attribute.ends_with?("_id")
|
83
|
+
humanize_class_name(attribute)
|
84
|
+
else
|
85
|
+
"#{self}|#{attribute.split('.').map!(&:humanize).join('|')}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This class is a concrete implementation of ConnectionAdapters::AbstractAdapter
|
4
|
+
# that eliminates all code paths attempting to open a connection to a real
|
5
|
+
# database backend.
|
6
|
+
module ActiveRecord
|
7
|
+
module ConnectionAdapters
|
8
|
+
class NullAdapter < SimpleDelegator
|
9
|
+
def schema_cache
|
10
|
+
NullSchemaCache.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# When run against a real database backend, ordinarily the SchemaCache
|
4
|
+
# would open a connection to the DB and attempt to retrieve schema
|
5
|
+
# information from it.
|
6
|
+
#
|
7
|
+
# Here, we declare that these ActiveRecord classes do not have any
|
8
|
+
# database-backed schema or column information. The structure of an
|
9
|
+
# ActiveRecord::BaseWithoutTable is purely an in-memory construct
|
10
|
+
# and is defined through the use of the `column` class methods.
|
11
|
+
module ActiveRecord
|
12
|
+
module ConnectionAdapters
|
13
|
+
class NullSchemaCache
|
14
|
+
def columns(*args)
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
|
18
|
+
def columns_hash(*args)
|
19
|
+
{}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/base_without_table'
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activerecord_base_without_table
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan De Villa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.7
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.0.7
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pg
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.18.4
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.18.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.5.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.5.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.5.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 9.0.6
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 9.0.6
|
83
|
+
description: Test harness for BaseWithoutTable migration to Rails 5
|
84
|
+
email:
|
85
|
+
- ryand@nulogy.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- MIT-LICENSE
|
91
|
+
- Rakefile
|
92
|
+
- lib/active_record/attributes_builder_without_table.rb
|
93
|
+
- lib/active_record/base_without_table.rb
|
94
|
+
- lib/active_record/connection_adapters/null_adapter.rb
|
95
|
+
- lib/active_record/connection_adapters/null_schema_cache.rb
|
96
|
+
- lib/activerecord_base_without_table.rb
|
97
|
+
- lib/tasks/base_without_table_migration_harness_tasks.rake
|
98
|
+
homepage: https://nulogy.com
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.7.7
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Test harness for BaseWithoutTable migration to Rails 5
|
122
|
+
test_files: []
|