updateable_views_inheritance 1.4.2 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.deepsource.toml +8 -0
- data/.github/workflows/build.yml +66 -0
- data/.gitignore +4 -1
- data/.vscode/settings.json +6 -0
- data/CHANGELOG.md +24 -8
- data/README.md +166 -0
- data/Rakefile +3 -3
- data/lib/updateable_views_inheritance/active_record.rb +3 -1
- data/lib/updateable_views_inheritance/postgresql_adapter.rb +205 -191
- data/lib/updateable_views_inheritance/version.rb +1 -1
- data/test/content_test.rb +2 -1
- data/test/dummy/app/assets/config/manifest.js +0 -0
- data/test/dummy/config/database.yml +1 -0
- data/test/install_generator_test.rb +2 -2
- data/test/instantiation_test.rb +38 -0
- data/test/migration_test.rb +3 -3
- data/test/schema_test.rb +32 -2
- data/test/single_table_inheritance.rb +1 -1
- data/test/test_helper.rb +21 -0
- data/updateable_views_inheritance.gemspec +8 -4
- metadata +81 -19
- data/README.rdoc +0 -121
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5a592cb214e5825bb4af87c5412ae3f91730d0e3882931f71bd16378ace7640a
|
4
|
+
data.tar.gz: 2fbf14052dde92e69724d574c0b5fb7b4d79297928220bc8bee5851cc8ee60ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4da55b7632575a0fba84248130308890f56dd726e6aaec835d3423b874a959d88ecf51dbf482795ba97869e5255411b9599b0117df61c6e70b3f095322c23fe
|
7
|
+
data.tar.gz: edd29da257c91e7d8a53df032bc70dd2317c78433637649e23285118b058109116259ed22efc86b8495f44301c5c6831c125e26565c1aa203ad00663205c8f6c
|
data/.deepsource.toml
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Build
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ "master" ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ "master" ]
|
15
|
+
|
16
|
+
permissions:
|
17
|
+
contents: read
|
18
|
+
|
19
|
+
jobs:
|
20
|
+
test:
|
21
|
+
runs-on: ubuntu-latest
|
22
|
+
services:
|
23
|
+
postgres:
|
24
|
+
image: postgres:9.6.24
|
25
|
+
ports:
|
26
|
+
- "5432:5432"
|
27
|
+
env:
|
28
|
+
POSTGRES_DB: updateable_views_inheritance_test
|
29
|
+
POSTGRES_USER: postgres
|
30
|
+
POSTGRES_PASSWORD: postgres
|
31
|
+
strategy:
|
32
|
+
matrix:
|
33
|
+
ruby-version: ['2.7']
|
34
|
+
env:
|
35
|
+
DATABASE_URL: "postgres://postgres:postgres@localhost:5432/updateable_views_inheritance_test"
|
36
|
+
steps:
|
37
|
+
- uses: actions/checkout@v4
|
38
|
+
with:
|
39
|
+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of Sonar analysis
|
40
|
+
|
41
|
+
- name: Set up Ruby
|
42
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
43
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
44
|
+
# uses: ruby/setup-ruby@v1
|
45
|
+
uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
|
46
|
+
with:
|
47
|
+
ruby-version: ${{ matrix.ruby-version }}
|
48
|
+
bundler: 1.17.3 # temporary set until rails 5 upgrade
|
49
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
50
|
+
|
51
|
+
- name: Run tests
|
52
|
+
run: bundle exec rake 2>/dev/null # disable warnings until ruby 3 upgrade
|
53
|
+
|
54
|
+
# From https://stackoverflow.com/questions/74199483/sonarcloud-ci-cant-find-source-files-for-ruby-simplecov-coverage
|
55
|
+
- name: Fix code coverage paths for DeepSource
|
56
|
+
working-directory: ./coverage
|
57
|
+
run: |
|
58
|
+
sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' .resultset.json
|
59
|
+
|
60
|
+
- name: Report test coverage to DeepSource
|
61
|
+
uses: deepsourcelabs/test-coverage-action@master
|
62
|
+
with:
|
63
|
+
key: ruby
|
64
|
+
coverage-file: ./coverage/.resultset.json
|
65
|
+
dsn: ${{ secrets.DEEPSOURCE_DSN }}
|
66
|
+
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
## 1.4.4 (09 October 2024)
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- Quote table and column names.
|
6
|
+
|
7
|
+
## 1.4.3 (01 October 2024)
|
8
|
+
|
9
|
+
Features:
|
10
|
+
|
11
|
+
- Add option to disable inheritance instantiation for less
|
12
|
+
database hits when loading large object collections from a
|
13
|
+
parent class.
|
14
|
+
|
15
|
+
- Add option to skip creating child table in migrations.
|
16
|
+
|
1
17
|
## 1.4.2 (28 March 2017)
|
2
18
|
|
3
19
|
Upgrade to Rails 4.2
|
@@ -15,31 +31,31 @@ Upgrade to Rails 4
|
|
15
31
|
|
16
32
|
Features:
|
17
33
|
|
18
|
-
-
|
34
|
+
- Rebuild views in all inheritance chains (must be run when upgrading from <= 1.2.1)
|
19
35
|
|
20
36
|
## 1.2.2 (18 August 2015)
|
21
37
|
|
22
38
|
Bugfixes:
|
23
39
|
|
24
|
-
-
|
40
|
+
- Fixed compatibility with Rails 3.2.19+ and ActiveRecord's prepared statements
|
25
41
|
|
26
42
|
## 1.2.1 (27 August 2014)
|
27
43
|
|
28
44
|
Bugfixes:
|
29
45
|
|
30
|
-
-
|
46
|
+
- Parent relations can be in a schema
|
31
47
|
|
32
48
|
## 1.2.0 (27 August 2014)
|
33
49
|
|
34
50
|
Features:
|
35
51
|
|
36
|
-
-
|
52
|
+
- Support for PostgreSQL schemas
|
37
53
|
|
38
54
|
## 1.1.2 (14 June 2013)
|
39
55
|
|
40
56
|
Bugfixes:
|
41
57
|
|
42
|
-
-
|
58
|
+
- Fixed generating migration on installation
|
43
59
|
|
44
60
|
Documentation:
|
45
61
|
|
@@ -49,17 +65,17 @@ Documentation:
|
|
49
65
|
|
50
66
|
Features:
|
51
67
|
|
52
|
-
-
|
68
|
+
- Gemified and released on rubygems.org
|
53
69
|
|
54
70
|
## 1.1.0 (13 June 2013)
|
55
71
|
|
56
72
|
Features:
|
57
73
|
|
58
|
-
-
|
74
|
+
- Updated for Rails 3.2.x
|
59
75
|
|
60
76
|
## 1.0.0 (14 September 2009)
|
61
77
|
|
62
78
|
Features:
|
63
79
|
|
64
80
|
- class_table_inheritance plugin has behaved stably in production for a year
|
65
|
-
-
|
81
|
+
- Supports Rails 2.1, 2.2 and 2.3
|
data/README.md
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# Class Table Inheritance
|
2
|
+
|
3
|
+
[![Build](https://github.com/tutuf/updateable_views_inheritance/actions/workflows/build.yml/badge.svg)](https://github.com/tutuf/updateable_views_inheritance/actions?query=workflow:build)
|
4
|
+
[![Coverage](https://app.deepsource.com/gh/tutuf/updateable_views_inheritance.svg/?label=code+coverage&show_trend=true&token=AMfm8-_-qDZoknMh9-8IYp3R)](https://app.deepsource.com/gh/tutuf/updateable_views_inheritance/)
|
5
|
+
|
6
|
+
Class Table Inheritance for ActiveRecord using updateable views
|
7
|
+
|
8
|
+
More about the pattern on
|
9
|
+
http://www.martinfowler.com/eaaCatalog/classTableInheritance.html. This gem
|
10
|
+
messes very little with Rails inheritance mechanism. Instead it relies on
|
11
|
+
updatable views in the database to represent classes in the inheritance chain.
|
12
|
+
The approach was [first suggested by John
|
13
|
+
Wilger](http://web.archive.org/web/20060408145717/johnwilger.com/articles/2005/09/29/class-table-inheritance-in-rails-with-postgresql).
|
14
|
+
|
15
|
+
|
16
|
+
# Requirements
|
17
|
+
|
18
|
+
Rails: 4.x
|
19
|
+
|
20
|
+
Ruby: 1.9.3+
|
21
|
+
|
22
|
+
Database: PostgreSQL only. Patches for other DBMS are welcome. Note that you are
|
23
|
+
not required to use updateable views, children relations can be tables with
|
24
|
+
some triggers involved.
|
25
|
+
|
26
|
+
# Usage
|
27
|
+
|
28
|
+
## Setup
|
29
|
+
|
30
|
+
* Add `gem 'updateable_views_inheritance'` to your `Gemfile`
|
31
|
+
* Run `rails generate updateable_views_inheritance:install && rake db:migrate`
|
32
|
+
* In `config/environment.rb` set `config.active_record.schema_format = :sql`
|
33
|
+
|
34
|
+
## Example
|
35
|
+
|
36
|
+
The database migration:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
class CtiExample < ActiveRecord::Migration
|
40
|
+
def self.up
|
41
|
+
create_table :locomotives do |t|
|
42
|
+
t.column :name, :string
|
43
|
+
t.column :max_speed, :integer
|
44
|
+
t.column :type, :string
|
45
|
+
end
|
46
|
+
|
47
|
+
create_child(:steam_locomotives, parent: :locomotives) do |t|
|
48
|
+
t.decimal :water_consumption, precision: 6, scale: 2
|
49
|
+
t.decimal :coal_consumption, precision: 6, scale: 2
|
50
|
+
end
|
51
|
+
|
52
|
+
create_child(:electric_locomotives,
|
53
|
+
table: :raw_electric_locomotives,
|
54
|
+
parent: :locomotives) do |t|
|
55
|
+
t.decimal :electricity_consumption, precision: 6, scale: 2
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.down
|
60
|
+
drop_child :steam_locomotives
|
61
|
+
drop_child :electric_locomotives
|
62
|
+
drop_table :locomotives
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
And the models:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class Locomotive
|
71
|
+
end
|
72
|
+
|
73
|
+
class SteamLocomotive < Locomotive
|
74
|
+
self.table_name = :steam_locomotives
|
75
|
+
end
|
76
|
+
|
77
|
+
class ElectricLocomotive < Locomotive
|
78
|
+
self.table_name = :electric_locomotives
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
Note that models of children classes must specify table name explicitly.
|
83
|
+
|
84
|
+
### Changing Columns in Underlying Tables
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
class RemoveColumnInParentTable < ActiveRecord::Migration
|
88
|
+
def self.up
|
89
|
+
remove_parent_and_children_views(:locomotives)
|
90
|
+
remove_column(:locomotives, :max_speed)
|
91
|
+
rename_column(:name, :title)
|
92
|
+
rebuild_parent_and_children_views(:locomotives)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
### Renaming Underlying Tables
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
remove_parent_and_children_views(:old_name)
|
101
|
+
rename_table(:old_name,:new_name)
|
102
|
+
execute "UPDATE updateable_views_inheritance SET child_aggregate_view = 'new_name' WHERE child_aggregate_view = 'old_name'"
|
103
|
+
execute "UPDATE updateable_views_inheritance SET parent_relation = 'new_name' WHERE parent_relation = 'old_name'"
|
104
|
+
rebuild_parent_and_children_views(:new_name)
|
105
|
+
```
|
106
|
+
|
107
|
+
### Removing Classes
|
108
|
+
|
109
|
+
Note that you should remove only leaf classes (i.e. those that do not have
|
110
|
+
descendants). If you want to erase a whole chain or part of chain you have to
|
111
|
+
remove first the leaves and then their ancestors. Use `drop_child(child_view)`
|
112
|
+
in migrations.
|
113
|
+
|
114
|
+
### Using parent class without instantiating subclass
|
115
|
+
|
116
|
+
If you don't want to make a second SQL query to the subclass table when you instantiate
|
117
|
+
parent class with `Locomotive.find(1)` use
|
118
|
+
```ruby
|
119
|
+
class Locomotive
|
120
|
+
self.disable_inheritance_instantiation = true
|
121
|
+
end
|
122
|
+
```
|
123
|
+
Quite handy for flat and wide class hierarchies (one parent class, many subclasses).
|
124
|
+
|
125
|
+
### Using existing table for inherited class
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
class CreateIkarusBus < ActiveRecord::Migration
|
129
|
+
def self.up
|
130
|
+
# table `tbl_ikarus_buses` exists in the database
|
131
|
+
end
|
132
|
+
create_child(:ikarus_buses,
|
133
|
+
table: :tbl_ikarus_buses,
|
134
|
+
parent: :buses,
|
135
|
+
skip_creating_child_table: true)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
```
|
139
|
+
Useful when converting legacy DB schema to use inheritance.
|
140
|
+
|
141
|
+
## Compatibility with Single Table Inheritance
|
142
|
+
|
143
|
+
The approach of this gem is completely independent from Rails built-in Single
|
144
|
+
Table Inheritance. STI and CLTI can safely be mixed in one inheritance chain.
|
145
|
+
|
146
|
+
## Testing Your App
|
147
|
+
|
148
|
+
If you use fixtures, you must run `rake updateable_views_inheritance:fixture` to
|
149
|
+
generate fixture for the updateable_views_inheritance table after you
|
150
|
+
add/remove classes from the hierarchy or change underlying table or view names.
|
151
|
+
**Without it primary key sequence for inheritors' tables won't be bumped to the
|
152
|
+
max and it might not be possible to save objects!** If you don't use fixtures
|
153
|
+
for the classes in the hierarchy you don't need to do that.
|
154
|
+
|
155
|
+
This gem re-enables referential integrity on fixture loading. This means that
|
156
|
+
`fixtures :all` may fail when there are foreign key constraints on tables. To
|
157
|
+
fix this, explicitly declare fixture load order in `test_helper.rb`:
|
158
|
+
|
159
|
+
```
|
160
|
+
fixtures :roots, :trunks, :leafs, ...
|
161
|
+
```
|
162
|
+
for all fixtures you want to load.
|
163
|
+
|
164
|
+
## Gem Development & Testing
|
165
|
+
|
166
|
+
In order to run gem tests, you have to be a superuser in PostgreSQL.
|
data/Rakefile
CHANGED
@@ -24,14 +24,14 @@ end
|
|
24
24
|
namespace :test do
|
25
25
|
desc 'Build the test database'
|
26
26
|
task :create_database do
|
27
|
-
%x( createdb updateable_views_inheritance_test )
|
27
|
+
%x( createdb updateable_views_inheritance_test ) unless ENV['CI']
|
28
28
|
end
|
29
29
|
|
30
30
|
desc 'Drop the test database'
|
31
31
|
task :drop_database do
|
32
|
-
%x( dropdb updateable_views_inheritance_test )
|
32
|
+
%x( dropdb updateable_views_inheritance_test ) unless ENV['CI']
|
33
33
|
end
|
34
34
|
|
35
35
|
desc 'Rebuild the test database'
|
36
36
|
task :rebuild_database => [:drop_database, :create_database]
|
37
|
-
end
|
37
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
module ActiveRecord #:nodoc:
|
2
2
|
class Base #:nodoc:
|
3
3
|
class << self
|
4
|
+
attr_accessor :disable_inheritance_instantiation
|
5
|
+
|
4
6
|
private
|
5
7
|
def instantiate_with_updateable_views_inheritance_support(attributes, column_types = {})
|
6
8
|
object = instantiate_without_updateable_views_inheritance_support(attributes, column_types = {})
|
7
|
-
if object.class.name == self.name
|
9
|
+
if object.class.name == self.name || self.disable_inheritance_instantiation
|
8
10
|
object
|
9
11
|
else
|
10
12
|
object.class.find(attributes.with_indifferent_access[:id])
|