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 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'
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :base_without_table do
3
+ # # Task goes here
4
+ # end
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: []