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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +6 -0
  4. data/app/assets/javascripts/gatherable/application.js +13 -0
  5. data/app/controllers/gatherable/application_controller.rb +43 -0
  6. data/app/models/data_point.rb +28 -0
  7. data/app/writers/controller_writer.rb +34 -0
  8. data/app/writers/migration_writer.rb +90 -0
  9. data/app/writers/model_writer.rb +36 -0
  10. data/config/routes.rb +2 -0
  11. data/lib/gatherable.rb +41 -0
  12. data/lib/gatherable/configuration.rb +19 -0
  13. data/lib/gatherable/engine.rb +5 -0
  14. data/lib/gatherable/version.rb +3 -0
  15. data/lib/generators/gatherable/USAGE +32 -0
  16. data/lib/generators/gatherable/gatherable_generator.rb +33 -0
  17. data/lib/generators/gatherable/templates/application_controller.rb +43 -0
  18. data/lib/generators/gatherable/templates/gatherable.rb +9 -0
  19. data/lib/tasks/db_tasks.rake +14 -0
  20. data/lib/tasks/gatherable_tasks.rake +6 -0
  21. data/lib/version.rb +3 -0
  22. data/spec/controllers/gatherable/application_controller_spec.rb +110 -0
  23. data/spec/dummy/Rakefile +6 -0
  24. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  25. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  26. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  27. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/spec/dummy/bin/bundle +3 -0
  29. data/spec/dummy/bin/rails +4 -0
  30. data/spec/dummy/bin/rake +4 -0
  31. data/spec/dummy/bin/setup +29 -0
  32. data/spec/dummy/config.ru +4 -0
  33. data/spec/dummy/config/application.rb +26 -0
  34. data/spec/dummy/config/boot.rb +5 -0
  35. data/spec/dummy/config/database.yml +11 -0
  36. data/spec/dummy/config/database.yml.travis +4 -0
  37. data/spec/dummy/config/environment.rb +5 -0
  38. data/spec/dummy/config/environments/development.rb +41 -0
  39. data/spec/dummy/config/environments/production.rb +79 -0
  40. data/spec/dummy/config/environments/test.rb +42 -0
  41. data/spec/dummy/config/initializers/assets.rb +11 -0
  42. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  43. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  44. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  45. data/spec/dummy/config/initializers/inflections.rb +16 -0
  46. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  47. data/spec/dummy/config/initializers/session_store.rb +3 -0
  48. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  49. data/spec/dummy/config/locales/en.yml +23 -0
  50. data/spec/dummy/config/routes.rb +3 -0
  51. data/spec/dummy/config/secrets.yml +5 -0
  52. data/spec/dummy/log/test.log +1550 -0
  53. data/spec/dummy/public/404.html +67 -0
  54. data/spec/dummy/public/422.html +67 -0
  55. data/spec/dummy/public/500.html +66 -0
  56. data/spec/dummy/public/favicon.ico +0 -0
  57. data/spec/lib/gatherable_spec.rb +88 -0
  58. data/spec/lib/generators/gatherable_generator_spec.rb +107 -0
  59. data/spec/models/data_point_spec.rb +44 -0
  60. data/spec/rails_helper.rb +57 -0
  61. data/spec/spec_helper.rb +92 -0
  62. 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,6 @@
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
+ Dir.glob('lib/tasks/*.rake').each { |r| load r}
@@ -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
@@ -0,0 +1,2 @@
1
+ #Gatherable::Engine.routes.draw do
2
+ #end
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,5 @@
1
+ module Gatherable
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Gatherable
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Gatherable
2
+ VERSION = "0.0.1"
3
+ 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