production_models 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +36 -0
- data/LICENSE.txt +22 -0
- data/README.md +84 -0
- data/Rakefile +1 -0
- data/lib/production/version.rb +3 -0
- data/lib/production.rb +71 -0
- data/production_models.gemspec +24 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 58a6836d7a856be664ab2523a95af7cda236e2ce
|
4
|
+
data.tar.gz: 0c6d3d0741d50c43e0fa62a79b181476d2ae2611
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c79e913e4a536e44ee1c5e0e6155b8812f2702f5cb49904a1a2e3709d5dc31aaa1ad2f4e5397fca5fb680213419f41d36dac7eb410b68c64a4634e246506a292
|
7
|
+
data.tar.gz: 640ff84f9692873e86f0e9a9ed81b66ac79f03bee60afa0aaa3f1b5147a20ccbf9a7c19bdf864710eca046f24a0fac6a6192ec45a847053dcdd3ec046a1ede5b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
production_models (0.0.1)
|
5
|
+
activerecord (~> 3.2)
|
6
|
+
database_cleaner (~> 1.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activemodel (3.2.14)
|
12
|
+
activesupport (= 3.2.14)
|
13
|
+
builder (~> 3.0.0)
|
14
|
+
activerecord (3.2.14)
|
15
|
+
activemodel (= 3.2.14)
|
16
|
+
activesupport (= 3.2.14)
|
17
|
+
arel (~> 3.0.2)
|
18
|
+
tzinfo (~> 0.3.29)
|
19
|
+
activesupport (3.2.14)
|
20
|
+
i18n (~> 0.6, >= 0.6.4)
|
21
|
+
multi_json (~> 1.0)
|
22
|
+
arel (3.0.2)
|
23
|
+
builder (3.0.4)
|
24
|
+
database_cleaner (1.0.1)
|
25
|
+
i18n (0.6.4)
|
26
|
+
multi_json (1.7.7)
|
27
|
+
rake (10.1.0)
|
28
|
+
tzinfo (0.3.37)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bundler (~> 1.3)
|
35
|
+
production_models!
|
36
|
+
rake
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Luciano Di Lucrezia
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# ProductionModels
|
2
|
+
|
3
|
+
Easily access your data in the production database from the console.
|
4
|
+
|
5
|
+
Ever wanted to take a peek in the production data while developing, or to
|
6
|
+
transfer data from one database to the other? With ProductionModels, you can
|
7
|
+
use the same classes to access both databases simultaneously.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'production_models'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install production_models
|
22
|
+
|
23
|
+
Once loaded, remember to load the class with:
|
24
|
+
|
25
|
+
require 'production'
|
26
|
+
|
27
|
+
(that's right, just `production` and not `production_models`)
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
There are two forms for accessing your production database:
|
32
|
+
|
33
|
+
1. Prepend `Production::` to your model's class and you're accessing the
|
34
|
+
production database (quicker but has caveats, see section below)
|
35
|
+
|
36
|
+
2. Use `Production.wrap(ModelClass)` to call `ModelClass` methods on the
|
37
|
+
production database (slower to type and execute, but safer)
|
38
|
+
|
39
|
+
You can specify any other connection defined in `config/database.yml` by
|
40
|
+
calling `Production.connection = :connection_name` or by passing a database
|
41
|
+
URI, just as you would with `ActiveRecord::Base.establish_connection` because,
|
42
|
+
well, that's what happens behind the scenes. By default, you're accessing the
|
43
|
+
database configured in the `production` section of the configuration file.
|
44
|
+
|
45
|
+
In addition you can sync tables between environments with
|
46
|
+
|
47
|
+
Production.push_from_development(ModelClass, AnotherModelClass, YetAnotherModelClass)
|
48
|
+
|
49
|
+
and similarly with
|
50
|
+
|
51
|
+
Production.pull_to_development(ModelClass, AnotherModelClass, YetAnotherModelClass)
|
52
|
+
|
53
|
+
**The destination tables will be truncated**, so please be super-duper careful
|
54
|
+
when you use these.
|
55
|
+
|
56
|
+
|
57
|
+
## Bugs / caveats
|
58
|
+
|
59
|
+
The namespace approach does some metaprogramming magic to do its dirty job,
|
60
|
+
which works fine if your models are in the main namespace (i.e. they live in
|
61
|
+
`app/models`), but can lead to unpredictable results if your models are
|
62
|
+
namespaced. In particular, if you have a situation where you have
|
63
|
+
|
64
|
+
class SomeClass < ActiveRecord::Base
|
65
|
+
class SomeOtherClass < ActiveRecord::Base
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
then `Production::SomeClass::SomeOtherClass` will **not** point to the
|
70
|
+
production database, but instead to the _development_ database! This happens
|
71
|
+
because Ruby resolves namespaces from left to right and I couldn't figure out a
|
72
|
+
way to trigger a `const_missing` on a constant that's actually there. In this
|
73
|
+
case, you'll have to use `Production.wrap(SomeClass::SomeOtherClass)` and
|
74
|
+
you'll get a class that will point to the right database.
|
75
|
+
|
76
|
+
If you have a solution for this, feel free to patch it on. ;-)
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
1. Fork it
|
81
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
82
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
83
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
84
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/production.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'production/version'
|
2
|
+
require 'database_cleaner'
|
3
|
+
|
4
|
+
class Production
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def const_missing(name)
|
8
|
+
namespace = self.name.split('::').tap(&:shift).join('::') # remove 'Production' from requested class namespace
|
9
|
+
"#{namespace}::#{name}".constantize rescue nil # fire autoload
|
10
|
+
if "#{namespace}".constantize.const_defined?(name)
|
11
|
+
case "#{namespace}::#{name}".constantize.class.to_s
|
12
|
+
when 'Module'
|
13
|
+
return Module.new.tap do |m|
|
14
|
+
m.extend(ClassMethods)
|
15
|
+
const_set(name, m)
|
16
|
+
end
|
17
|
+
when 'Class'
|
18
|
+
klass = Class.new("#{namespace}::#{name}".constantize)
|
19
|
+
klass.establish_connection(connection)
|
20
|
+
return klass
|
21
|
+
end
|
22
|
+
end
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
self.extend(ClassMethods)
|
28
|
+
|
29
|
+
def self.connection
|
30
|
+
@connection || :production
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.connection=(conn)
|
34
|
+
@connection = conn
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.wrap(klass)
|
38
|
+
Class.new(klass).tap { |c| c.establish_connection(connection) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.push_from_development(*classes)
|
42
|
+
classes.flatten.each do |klass|
|
43
|
+
prod_klass = wrap(klass)
|
44
|
+
cleaner = DatabaseCleaner::Base.new(:active_record, connection: prod_klass)
|
45
|
+
cleaner.clean_with(:truncation, only: [ prod_klass.table_name ])
|
46
|
+
prod_klass.transaction do
|
47
|
+
klass.find_each do |i|
|
48
|
+
prod_klass.new.tap do |j|
|
49
|
+
j.assign_attributes(i.attributes, without_protection: true)
|
50
|
+
end.save!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.pull_to_development(*classes)
|
57
|
+
classes.flatten.each do |klass|
|
58
|
+
prod_klass = wrap(klass)
|
59
|
+
cleaner = DatabaseCleaner::Base.new(:active_record, connection: klass)
|
60
|
+
cleaner.clean_with(:truncation, only: [ klass.table_name ])
|
61
|
+
klass.transaction do
|
62
|
+
prod_klass.find_each do |i|
|
63
|
+
klass.new.tap do |j|
|
64
|
+
j.assign_attributes(i.attributes, without_protection: true)
|
65
|
+
end.save!
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'production/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "production_models"
|
8
|
+
spec.version = Production::VERSION
|
9
|
+
spec.authors = ["Luciano Di Lucrezia"]
|
10
|
+
spec.email = ["luciano.dilucrezia@gmail.com"]
|
11
|
+
spec.description = %q{Access your production models in development environment.}
|
12
|
+
spec.summary = %q{Wraps production ActiveRecord models in a new namespace for easy access and transfer from development environment.}
|
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_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_runtime_dependency "database_cleaner", "~> 1.0"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: production_models
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Luciano Di Lucrezia
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: database_cleaner
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
description: Access your production models in development environment.
|
56
|
+
email:
|
57
|
+
- luciano.dilucrezia@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/production.rb
|
69
|
+
- lib/production/version.rb
|
70
|
+
- production_models.gemspec
|
71
|
+
homepage: ''
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.0.3
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Wraps production ActiveRecord models in a new namespace for easy access and
|
95
|
+
transfer from development environment.
|
96
|
+
test_files: []
|