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
         
     |