orphanage 0.1.0 → 0.3.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 +4 -4
- data/LICENSE +21 -0
- data/README.md +92 -0
- data/lib/generators/orphanage/init_generator.rb +72 -0
- data/lib/generators/orphanage/templates/migration.rb.erb +14 -0
- data/lib/generators/orphanage/templates/model.rb.erb +7 -0
- metadata +20 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96c180f014edb46218c44e21d23954cc93ef61ea
|
|
4
|
+
data.tar.gz: 67b4ae194d309a8d16254944417432878cab0ff8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 221a8c0b2d28fae31cbe96d2bd262340e1e93443ee5acea7bd4b499be9631b9d1b8b89d50c608e94cab845daff626ea7f122f6fe02d51f328a33bae14dd8f8cc
|
|
7
|
+
data.tar.gz: 1d1b52c071e2c96ad270f21ab3df6616fe4d54dfddc7d41c346155341bc97386f07a1e1559f07be80c4054a01526151d97667fc188e1f72996e23dae8d97f184
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Jacob Stoebel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Orphanage:
|
|
2
|
+
#### A simple library for storing temporary orphan records.
|
|
3
|
+
|
|
4
|
+
Orphanage is a super lightweight library for persisting orphan records. Let's say you have some data but don't yet know all of its foreign keys. Orphanage streamlines the process of keeping it in a temporary table and then, when all foreign keys become available, transferring it to the proper table in the database.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
gem 'orphanage'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## A simple use case
|
|
13
|
+
|
|
14
|
+
Let's say you are have a database with `students` having many `exams`. Exam results come in to your database via an external source, but sometimes you can't match them up perfectly. A person may have a different last name due to marriage for example. When `exam` records can not be identified to a `student` they should be stored in the table `exam_temps`. Later when an an admin user audits the ambiguous records and provides a `student`, the record is transferred from`exam_temps` to `exams`.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Model Creation
|
|
20
|
+
|
|
21
|
+
#### Using the generator
|
|
22
|
+
|
|
23
|
+
Assuming your home model already exists and its corresponding table exists in the database run `rails generate orphanage:init <HomeModelName>`. For example:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
rails generate orphanage:init Exam
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
generates a model for your orphan table as well as a migration file that will give you all of the columns existing in the home model. You'll also get any other files you would expect when running `rails generate model` (such as tests, factories, fixtures, etc as the case may be)
|
|
30
|
+
|
|
31
|
+
#### Manually
|
|
32
|
+
|
|
33
|
+
Creating an orphan model by hand isn't much more work. By default orphanage expects the model to have `Temp` appended to the original, so for example an orphan model to `Exam` would be `ExamTemp`.
|
|
34
|
+
|
|
35
|
+
Then inside that model:
|
|
36
|
+
```
|
|
37
|
+
require 'orphanage'
|
|
38
|
+
|
|
39
|
+
class ExamTemp < ActiveRecord::Base
|
|
40
|
+
include Orphanage
|
|
41
|
+
orphan
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
From there you can add temporary records to this orphan table like you normally would.
|
|
46
|
+
|
|
47
|
+
#### Adoption
|
|
48
|
+
|
|
49
|
+
Transferring a model to its home table is done by calling the `adopt` method. For example:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
# record can't be stored in exam table because it has no student_id
|
|
53
|
+
exam_temp = ExamTemp.create!({:score => 150,
|
|
54
|
+
:taken_on => Date.today,
|
|
55
|
+
:first_name => "Jacob",
|
|
56
|
+
:last_name => "Stoebel"
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
#later, a student_id is provided for this record
|
|
60
|
+
exam_temp.adopt({:student_id => 1})
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Calling `adopt`, if successful, will return the created permanent record. The temporary record will stick around unless you explicitly as for it to be destroyed (see below)
|
|
64
|
+
|
|
65
|
+
## Customizations
|
|
66
|
+
|
|
67
|
+
You can customize the behavior at the model level and/or the instance level with instance level customizations taking precedence. To do so, pass in a hash with any of the following keys.
|
|
68
|
+
|
|
69
|
+
- __home__ The ActiveRecord model to which orphan records will be transferred to when made permanent. By default the value is generated by removing `Temp` from the orphan model (example: `ExamTemp` -> `Exam`)
|
|
70
|
+
- __destroy_on_adopt__ (boolean) if the orphan record should be destroyed after successful transfer of record. Defaults to `false`.
|
|
71
|
+
- __update_time_stamps__ a hash of booleans with the following keys
|
|
72
|
+
- __created__ if the `created_at` timestamp should be persisted from the orphan record. Defaults to `true`.
|
|
73
|
+
- __updated__ if the `updated_at` timestamp should be persisted from the orphan record. Defaults to `true`.
|
|
74
|
+
|
|
75
|
+
### Examples
|
|
76
|
+
|
|
77
|
+
Let's say our orphan model is `ExamTemp`
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
# define a different home class throughout the orphan class...
|
|
81
|
+
orphan :home => Examination
|
|
82
|
+
|
|
83
|
+
# ... or inside just this instance
|
|
84
|
+
temp_exam.adopt({:student_id => 1}, {:home => Examination})
|
|
85
|
+
|
|
86
|
+
# don't destroy temp records after adoption
|
|
87
|
+
orphan :destroy_on_adopt => false
|
|
88
|
+
|
|
89
|
+
# for this instance, don't update the timestamps after adoption
|
|
90
|
+
temp_exam.adopt({:student_id => 1}, {:update_timestamps => {:created => false, :updated => false}})
|
|
91
|
+
|
|
92
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'rails/generators/base'
|
|
2
|
+
|
|
3
|
+
module Orphanage
|
|
4
|
+
|
|
5
|
+
class InitGenerator < Rails::Generators::Base
|
|
6
|
+
containing_dir = File.expand_path("..", __FILE__)
|
|
7
|
+
template_dir = File.join(containing_dir, 'templates')
|
|
8
|
+
source_root File.expand_path(template_dir)
|
|
9
|
+
|
|
10
|
+
argument :home_model_name, :type => :string
|
|
11
|
+
|
|
12
|
+
def ensure_home_model_and_table_exists
|
|
13
|
+
|
|
14
|
+
begin
|
|
15
|
+
home_model
|
|
16
|
+
rescue NameError => e
|
|
17
|
+
fail "Home model not found. Plese generate it first."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
table_exists = ActiveRecord::Base.connection.data_source_exists? home_table_name
|
|
21
|
+
fail "table #{home_table_name} does not exist. Stopping." if !table_exists
|
|
22
|
+
|
|
23
|
+
end # ensure_home_model_exists
|
|
24
|
+
|
|
25
|
+
def generate_model
|
|
26
|
+
generate "model #{home_model_name}Temp --skip-migration"
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def orphanize_model
|
|
31
|
+
# change the model to be an orphan model
|
|
32
|
+
puts "replacing model..."
|
|
33
|
+
template "model.rb.erb", "app/models/#{home_file_name}_temp.rb", force: true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def create_migration
|
|
37
|
+
puts "creating migration file..."
|
|
38
|
+
migration_file_name = "#{Time.now.utc.strftime("%Y%m%d%H%M%S")}_create_#{home_file_name}_temps.rb"
|
|
39
|
+
template "migration.rb.erb", "db/migrate/#{migration_file_name}"
|
|
40
|
+
end # create_migration
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def home_model
|
|
45
|
+
home_model_name.constantize
|
|
46
|
+
end # home_model
|
|
47
|
+
|
|
48
|
+
def home_file_name
|
|
49
|
+
home_model_name.underscore
|
|
50
|
+
end # file_name
|
|
51
|
+
|
|
52
|
+
def home_table_name
|
|
53
|
+
home_file_name.pluralize
|
|
54
|
+
end # home_table_name
|
|
55
|
+
|
|
56
|
+
def orphan_table_name
|
|
57
|
+
(home_model_name + "Temp").underscore.pluralize
|
|
58
|
+
end # orphan_table_name
|
|
59
|
+
|
|
60
|
+
def migration_columns
|
|
61
|
+
# get all column names
|
|
62
|
+
needed_cols = home_model.columns.select { |col| !%w(id created_at updated_at).include? col.name }
|
|
63
|
+
|
|
64
|
+
# returns an array of strings each representing a single column to add in the migration.
|
|
65
|
+
migrations = needed_cols.map {|col| "t.#{col.type} :#{col.name}, null: #{col.null}" }
|
|
66
|
+
|
|
67
|
+
return migrations
|
|
68
|
+
|
|
69
|
+
end # orphan_columns
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class Create<%= home_model_name %>Temps < ActiveRecord::Migration
|
|
2
|
+
def up
|
|
3
|
+
create_table :<%= orphan_table_name -%> do |t|
|
|
4
|
+
<%- migration_columns.each do |col| %>
|
|
5
|
+
<%= col %>
|
|
6
|
+
<% end %>
|
|
7
|
+
t.timestamps
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def down
|
|
12
|
+
drop_table :<%= orphan_table_name -%>
|
|
13
|
+
end
|
|
14
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: orphanage
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jacob Stoebel
|
|
@@ -78,12 +78,31 @@ dependencies:
|
|
|
78
78
|
- - "~>"
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
80
|
version: 0.10.4
|
|
81
|
+
- !ruby/object:Gem::Dependency
|
|
82
|
+
name: rails
|
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - "~>"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '5.0'
|
|
88
|
+
type: :development
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - "~>"
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '5.0'
|
|
81
95
|
description: A simple library for storing temporary orphan records.
|
|
82
96
|
email: jstoebel@gmail.com
|
|
83
97
|
executables: []
|
|
84
98
|
extensions: []
|
|
85
99
|
extra_rdoc_files: []
|
|
86
100
|
files:
|
|
101
|
+
- LICENSE
|
|
102
|
+
- README.md
|
|
103
|
+
- lib/generators/orphanage/init_generator.rb
|
|
104
|
+
- lib/generators/orphanage/templates/migration.rb.erb
|
|
105
|
+
- lib/generators/orphanage/templates/model.rb.erb
|
|
87
106
|
- lib/orphanage.rb
|
|
88
107
|
homepage: https://github.com/jstoebel/orphanage
|
|
89
108
|
licenses:
|