gatherable 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/MIT-LICENSE +20 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/gatherable/application.js +13 -0
- data/app/controllers/gatherable/application_controller.rb +43 -0
- data/app/models/data_point.rb +28 -0
- data/app/writers/controller_writer.rb +34 -0
- data/app/writers/migration_writer.rb +90 -0
- data/app/writers/model_writer.rb +36 -0
- data/config/routes.rb +2 -0
- data/lib/gatherable.rb +41 -0
- data/lib/gatherable/configuration.rb +19 -0
- data/lib/gatherable/engine.rb +5 -0
- data/lib/gatherable/version.rb +3 -0
- data/lib/generators/gatherable/USAGE +32 -0
- data/lib/generators/gatherable/gatherable_generator.rb +33 -0
- data/lib/generators/gatherable/templates/application_controller.rb +43 -0
- data/lib/generators/gatherable/templates/gatherable.rb +9 -0
- data/lib/tasks/db_tasks.rake +14 -0
- data/lib/tasks/gatherable_tasks.rake +6 -0
- data/lib/version.rb +3 -0
- data/spec/controllers/gatherable/application_controller_spec.rb +110 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +11 -0
- data/spec/dummy/config/database.yml.travis +4 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +5 -0
- data/spec/dummy/log/test.log +1550 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/lib/gatherable_spec.rb +88 -0
- data/spec/lib/generators/gatherable_generator_spec.rb +107 -0
- data/spec/models/data_point_spec.rb +44 -0
- data/spec/rails_helper.rb +57 -0
- data/spec/spec_helper.rb +92 -0
- metadata +243 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 09b8a7e4dbf788cde1816d9c319af7817648d106
|
4
|
+
data.tar.gz: c52691404ee19dd12f5eb7be2752495e2f27a210
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1e9b02a9b1aa75cb979d40efb00ede2c2e59e3067d8fc8859f7c5f04950409016cdee746abeb9e65e6d405876f2e8b4574d97f22153859b6ae1505f07664598f
|
7
|
+
data.tar.gz: 0e3f799004046b602253c04377ab576a40532bd4e5d84dd57a9962c3265a5d27fbd7e45de5aaf15d36d163f22777c199b0c0abd6c8ac16d0e8a40a02643b6304
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Daniel Schepers
|
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,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Gatherable
|
2
|
+
class ApplicationController < ::ActionController::Base
|
3
|
+
def show
|
4
|
+
render :json => model_class.find(params[model_id]), :status => :found
|
5
|
+
rescue ActiveRecord::RecordNotFound => e
|
6
|
+
render :json => { :errors => e.message}, :status => :not_found
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
render :json => model_class.create(model_params), :status => :created
|
11
|
+
rescue ActionController::ParameterMissing => e
|
12
|
+
render :json => { :errors => e.message}, :status => :unprocessable_entity
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def model_class
|
18
|
+
Object.const_get(model_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def model_name
|
22
|
+
self.class.to_s.chomp('Controller').singularize
|
23
|
+
end
|
24
|
+
|
25
|
+
def model_id
|
26
|
+
"#{unmodularized_model_name}_id"
|
27
|
+
end
|
28
|
+
|
29
|
+
def unmodularized_model_name
|
30
|
+
model_name.split('::').last.downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
def model_params
|
34
|
+
params.require(unmodularized_model_name).permit(
|
35
|
+
*model_class.column_names
|
36
|
+
).merge(global_identifier => params[global_identifier])
|
37
|
+
end
|
38
|
+
|
39
|
+
def global_identifier
|
40
|
+
Gatherable.config.global_identifier
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class DataPoint
|
2
|
+
attr_reader :name, :data_type
|
3
|
+
def initialize(name, data_type)
|
4
|
+
@name = name
|
5
|
+
@data_type = data_type
|
6
|
+
end
|
7
|
+
|
8
|
+
def class_name
|
9
|
+
name.to_s.classify
|
10
|
+
end
|
11
|
+
|
12
|
+
def controller_name
|
13
|
+
"#{class_name.pluralize}Controller"
|
14
|
+
end
|
15
|
+
|
16
|
+
def classify
|
17
|
+
return Gatherable.const_get(class_name) if Gatherable.const_defined?(class_name)
|
18
|
+
klass = Gatherable.const_set(class_name, Class.new(ActiveRecord::Base))
|
19
|
+
klass.table_name = name.to_s.pluralize
|
20
|
+
klass.table_name_prefix = Gatherable.config.schema_name + '.'
|
21
|
+
klass
|
22
|
+
end
|
23
|
+
|
24
|
+
def controllerify
|
25
|
+
return Gatherable.const_get(controller_name) if Gatherable.const_defined?(controller_name)
|
26
|
+
Gatherable.const_set(controller_name, Class.new(Gatherable::ApplicationController))
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class ControllerWriter
|
2
|
+
attr_reader :data_point
|
3
|
+
def initialize(data_point)
|
4
|
+
@data_point = data_point
|
5
|
+
end
|
6
|
+
|
7
|
+
def write
|
8
|
+
if File.exists?(filename)
|
9
|
+
puts "Controller already defined for #{data_point.name}. Skipping"
|
10
|
+
return
|
11
|
+
end
|
12
|
+
FileUtils.mkdir_p('app/controllers/gatherable')
|
13
|
+
File.open(filename, 'w') do |f|
|
14
|
+
f.puts controller_contents
|
15
|
+
end
|
16
|
+
puts "created #{filename}" if File.exists?(filename)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def filename
|
22
|
+
controller_file = "#{data_point.name.to_s.pluralize}_controller.rb"
|
23
|
+
File.join(Rails.root, 'app', 'controllers', 'gatherable', controller_file)
|
24
|
+
end
|
25
|
+
|
26
|
+
def controller_contents
|
27
|
+
<<-controller
|
28
|
+
module Gatherable
|
29
|
+
class #{data_point.controller_name} < Gatherable::ApplicationController
|
30
|
+
end
|
31
|
+
end
|
32
|
+
controller
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class MigrationWriter
|
2
|
+
attr_reader :data_point
|
3
|
+
|
4
|
+
def initialize(data_point)
|
5
|
+
@data_point = data_point
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.write_schema_migration
|
9
|
+
FileUtils.mkdir_p('db/migrate')
|
10
|
+
return if schema_migration_created?
|
11
|
+
File.open(schema_migration, 'w') do |f|
|
12
|
+
f.puts <<-schema_migration
|
13
|
+
class CreateGatherableSchema < ActiveRecord::Migration
|
14
|
+
def up
|
15
|
+
create_schema '#{Gatherable.config.schema_name}'
|
16
|
+
end
|
17
|
+
|
18
|
+
def down
|
19
|
+
drop_schema '#{Gatherable.config.schema_name}'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
schema_migration
|
23
|
+
end
|
24
|
+
puts "created #{schema_migration}" if File.exists?(schema_migration)
|
25
|
+
end
|
26
|
+
|
27
|
+
def write
|
28
|
+
if matching_migrations.present?
|
29
|
+
puts already_found_message
|
30
|
+
return
|
31
|
+
end
|
32
|
+
FileUtils.mkdir_p('db/migrate')
|
33
|
+
filename = "db/migrate/#{self.class.unique_timestamp}_#{file_suffix}"
|
34
|
+
File.open(filename, 'w') do |f|
|
35
|
+
f.puts file_template
|
36
|
+
end
|
37
|
+
puts "created #{filename}" if File.exists?(filename)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def self.unique_timestamp
|
43
|
+
t = Time.now
|
44
|
+
t += 1 while Dir[File.join('db', 'migrate', "#{t.strftime("%Y%m%d%H%M%S")}*.rb")].present?
|
45
|
+
t.strftime("%Y%m%d%H%M%S")
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.schema_migration_created?
|
49
|
+
Dir[File.join('db', 'migrate', "*create_gatherable_schema.rb")].present?
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.schema_migration
|
53
|
+
"db/migrate/#{unique_timestamp}_create_gatherable_schema.rb"
|
54
|
+
end
|
55
|
+
|
56
|
+
def table_name
|
57
|
+
@table_name ||= data_point.classify.table_name
|
58
|
+
end
|
59
|
+
|
60
|
+
def file_template
|
61
|
+
data_type = data_point.data_type.to_s
|
62
|
+
<<-template
|
63
|
+
class CreateGatherable#{table_name.classify} < ActiveRecord::Migration
|
64
|
+
def up
|
65
|
+
create_table '#{Gatherable.config.schema_name}.#{table_name}', :primary_key => '#{data_point.name}_id' do |t|
|
66
|
+
t.#{data_type} :#{data_point.name}, :null => false
|
67
|
+
t.string :#{Gatherable.config.global_identifier}, :index => true
|
68
|
+
t.timestamps :null => false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def down
|
73
|
+
drop_table '#{Gatherable.config.schema_name}.#{table_name}'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
template
|
77
|
+
end
|
78
|
+
|
79
|
+
def file_suffix
|
80
|
+
@file_suffix ||= "create_gatherable_#{table_name.singularize}.rb"
|
81
|
+
end
|
82
|
+
|
83
|
+
def already_found_message
|
84
|
+
"migrations #{matching_migrations} already exist. Skipping migration for #{data_point.name}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def matching_migrations
|
88
|
+
@matches ||= Dir[File.join('db', 'migrate', "*#{file_suffix}")]
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class ModelWriter
|
2
|
+
attr_reader :data_point
|
3
|
+
def initialize(data_point)
|
4
|
+
@data_point = data_point
|
5
|
+
end
|
6
|
+
|
7
|
+
def write
|
8
|
+
if File.exists?(filename)
|
9
|
+
puts "model already defined for #{data_point.name}. Skipping"
|
10
|
+
return
|
11
|
+
end
|
12
|
+
FileUtils.mkdir_p('app/models/gatherable')
|
13
|
+
File.open(filename, 'w') do |f|
|
14
|
+
f.puts model_contents
|
15
|
+
end
|
16
|
+
puts "created #{filename}" if File.exists?(filename)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def filename
|
22
|
+
model_file = "#{data_point.name}.rb"
|
23
|
+
File.join(Rails.root, 'app', 'models', 'gatherable', model_file)
|
24
|
+
end
|
25
|
+
|
26
|
+
def model_contents
|
27
|
+
<<-model
|
28
|
+
module Gatherable
|
29
|
+
class #{data_point.class_name} < ActiveRecord::Base
|
30
|
+
self.table_name = '#{data_point.name.to_s.pluralize}'
|
31
|
+
self.table_name_prefix = 'gatherable.'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
model
|
35
|
+
end
|
36
|
+
end
|
data/config/routes.rb
ADDED
data/lib/gatherable.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "gatherable/engine"
|
2
|
+
require "gatherable/configuration"
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
module Gatherable
|
6
|
+
class << self
|
7
|
+
def configure
|
8
|
+
return unless configuration.empty?
|
9
|
+
yield configuration
|
10
|
+
create_models
|
11
|
+
create_controllers
|
12
|
+
create_routes
|
13
|
+
end
|
14
|
+
|
15
|
+
def configuration
|
16
|
+
@configuration ||= Configuration.new
|
17
|
+
end
|
18
|
+
alias :config :configuration
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def create_models
|
23
|
+
config.data_points.map(&:classify)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_controllers
|
27
|
+
config.data_points.map(&:controllerify)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_routes
|
31
|
+
global_identifier = config.global_identifier
|
32
|
+
Gatherable::Engine.routes.draw do #would this wipe away whatever's in config/routes.rb?
|
33
|
+
Gatherable.config.data_points.map{ |dp| dp.name.to_s.pluralize }.each do |data_point|
|
34
|
+
scope :path => "/:#{global_identifier}" do
|
35
|
+
resources data_point.to_sym, :only => [:show, :create], :param => "#{data_point.singularize}_id"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Gatherable
|
2
|
+
class Configuration
|
3
|
+
delegate :empty?, :to => :data_points
|
4
|
+
attr_accessor :global_identifier
|
5
|
+
attr_writer :schema_name
|
6
|
+
|
7
|
+
def data_point(name, data_type)
|
8
|
+
data_points << DataPoint.new(name, data_type)
|
9
|
+
end
|
10
|
+
|
11
|
+
def data_points
|
12
|
+
@data_points ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def schema_name
|
16
|
+
@schema_name || 'gatherable'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Uses:
|
2
|
+
--------------------------------------
|
3
|
+
|
4
|
+
rails generate gatherable initializer
|
5
|
+
|
6
|
+
This will create:
|
7
|
+
config/initializers/gatherable.rb
|
8
|
+
|
9
|
+
--------------------------------------
|
10
|
+
|
11
|
+
rails generate gatherable migrations
|
12
|
+
|
13
|
+
This will create migrations for each data_point in
|
14
|
+
config/initializers/gatherable.rb
|
15
|
+
|
16
|
+
--------------------------------------
|
17
|
+
|
18
|
+
rails generate gatherable models
|
19
|
+
|
20
|
+
This will create models for each data_point in
|
21
|
+
config/initializers/gatherable.rb. The new models
|
22
|
+
will be stored in app/models/gatherable/
|
23
|
+
|
24
|
+
--------------------------------------
|
25
|
+
|
26
|
+
rails generate gatherable controllers
|
27
|
+
|
28
|
+
This will create models for each data_point in
|
29
|
+
config/initializers/gatherable.rb. The new models
|
30
|
+
will be stored in app/controllers/gatherable/
|
31
|
+
|
32
|
+
--------------------------------------
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
class GatherableGenerator < Rails::Generators::NamedBase
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
def generate
|
5
|
+
send "generate_#{file_name}"
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def generate_initializer
|
11
|
+
copy_file "gatherable.rb", "config/initializers/gatherable.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_migrations
|
15
|
+
MigrationWriter.write_schema_migration
|
16
|
+
Gatherable.config.data_points.each do |data_point|
|
17
|
+
MigrationWriter.new(data_point).write
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_models
|
22
|
+
Gatherable.config.data_points.each do |data_point|
|
23
|
+
ModelWriter.new(data_point).write
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_controllers
|
28
|
+
copy_file 'application_controller.rb', 'app/controllers/gatherable/application_controller.rb'
|
29
|
+
Gatherable.config.data_points.each do |data_point|
|
30
|
+
ControllerWriter.new(data_point).write
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Gatherable
|
2
|
+
class ApplicationController < ::ActionController::Base
|
3
|
+
def show
|
4
|
+
render :json => model_class.find(params[model_id]), :status => :found
|
5
|
+
rescue ActiveRecord::RecordNotFound => e
|
6
|
+
render :json => { :errors => e.message}, :status => :not_found
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
render :json => model_class.create(model_params), :status => :created
|
11
|
+
rescue ActionController::ParameterMissing => e
|
12
|
+
render :json => { :errors => e.message}, :status => :unprocessable_entity
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def model_class
|
18
|
+
Object.const_get(model_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def model_name
|
22
|
+
self.class.to_s.chomp('Controller').singularize
|
23
|
+
end
|
24
|
+
|
25
|
+
def model_id
|
26
|
+
"#{unmodularized_model_name}_id"
|
27
|
+
end
|
28
|
+
|
29
|
+
def unmodularized_model_name
|
30
|
+
model_name.split('::').last.downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
def model_params
|
34
|
+
params.require(unmodularized_model_name).permit(
|
35
|
+
*model_class.column_names
|
36
|
+
).merge(global_identifier => params[global_identifier])
|
37
|
+
end
|
38
|
+
|
39
|
+
def global_identifier
|
40
|
+
Gatherable.config.global_identifier
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|