mappable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +87 -0
  3. data/Rakefile +32 -0
  4. data/app/assets/javascripts/mappable/application.js +9 -0
  5. data/app/assets/javascripts/mappable/mappings.js +2 -0
  6. data/app/assets/javascripts/mappable/maps.js +2 -0
  7. data/app/assets/stylesheets/mappable/application.css +7 -0
  8. data/app/assets/stylesheets/mappable/mappings.css +4 -0
  9. data/app/assets/stylesheets/mappable/maps.css +4 -0
  10. data/app/assets/stylesheets/scaffold.css +56 -0
  11. data/app/controllers/mappable/application_controller.rb +4 -0
  12. data/app/controllers/mappable/mappings_controller.rb +54 -0
  13. data/app/controllers/mappable/maps_controller.rb +46 -0
  14. data/app/helpers/mappable/application_helper.rb +4 -0
  15. data/app/helpers/mappable/mappings_helper.rb +4 -0
  16. data/app/helpers/mappable/maps_helper.rb +4 -0
  17. data/app/models/mappable/map.rb +19 -0
  18. data/app/models/mappable/mapping.rb +6 -0
  19. data/app/views/mappable/mappings/_form.html.erb +26 -0
  20. data/app/views/mappable/mappings/edit.html.erb +6 -0
  21. data/app/views/mappable/mappings/index.html.erb +25 -0
  22. data/app/views/mappable/mappings/new.html.erb +5 -0
  23. data/app/views/mappable/mappings/show.html.erb +19 -0
  24. data/app/views/mappable/maps/_form.html.erb +47 -0
  25. data/app/views/mappable/maps/edit.html.erb +6 -0
  26. data/app/views/mappable/maps/index.html.erb +29 -0
  27. data/app/views/mappable/maps/new.html.erb +5 -0
  28. data/app/views/mappable/maps/show.html.erb +25 -0
  29. data/config/routes.rb +25 -0
  30. data/db/migrate/20110919042052_create_mappable_maps.rb +12 -0
  31. data/db/migrate/20110919042056_create_mappable_mappings.rb +12 -0
  32. data/lib/generators/mappable/views/USAGE +20 -0
  33. data/lib/generators/mappable/views/views_generator.rb +20 -0
  34. data/lib/mappable.rb +6 -0
  35. data/lib/mappable/engine.rb +9 -0
  36. data/lib/mappable/map_route.rb +27 -0
  37. data/lib/mappable/map_router.rb +22 -0
  38. data/lib/mappable/version.rb +3 -0
  39. data/lib/tasks/mappable_tasks.rake +4 -0
  40. metadata +156 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 Mike Bannister
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/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Mappable #
2
+
3
+ Lightweight string mappings engine for Rails
4
+
5
+ ## Synopsis ##
6
+
7
+ Provides models and a UI for creating and maintaining string pairs. A tiny DSL is included so developers to easily make use of the generated data. The UI allows system administrators to create groups of string pairs that can be maintained by non-technical people.
8
+
9
+ We use this tool to map account names in a legacy system, where we don't control the names, to their corresponding names in our in-house system.
10
+
11
+ ## Installation ##
12
+
13
+ Add it to your `Gemfile`
14
+
15
+ gem 'mappable'
16
+
17
+ Bundle it up
18
+
19
+ bundle install
20
+
21
+ Install the migrations and apply them
22
+
23
+ rake mappable:install:migrations
24
+ rake db:migrate
25
+
26
+ The migrations will add tables similar to this
27
+
28
+ create_table "mappable_mappings", :force => true do |t|
29
+ t.integer "map_id"
30
+ t.string "from"
31
+ t.string "to"
32
+ end
33
+
34
+ create_table "mappable_maps", :force => true do |t|
35
+ t.string "subject"
36
+ t.string "attr"
37
+ t.string "from"
38
+ t.string "to"
39
+ end
40
+
41
+ Mount the engine
42
+
43
+ mount Mappable::Engine => '/map'
44
+
45
+ You can use the included generator to copy the views if you'd like to customize them
46
+
47
+ rails generate mappable:views
48
+
49
+ Definitions
50
+
51
+ * **Mappings**: String pairs that map to each other
52
+
53
+ - [http://localhost:3000/map/account/name](http://localhost:3000/map/account/name)
54
+
55
+ * **Maps**: A group of mappings and relevant metadata.
56
+
57
+ - [http://localhost:3000/map](http://localhost:3000/maps)
58
+
59
+ ## Example usage ##
60
+
61
+ Given the following records
62
+
63
+ ### Map ###
64
+
65
+ id = 1
66
+ subject = 'account'
67
+ attr = 'name'
68
+ from = 'legacy'
69
+ to = 'current'
70
+
71
+ ### Mapping ###
72
+
73
+ id = 1
74
+ map_id = 1
75
+ from = 'Old Account Name'
76
+ to = 'New Account Name'
77
+
78
+ Now you can map strings in either direction using the following grammar
79
+
80
+ LegacyAccountName("Old Account Name").to_current #=> "New Account Name"
81
+ CurrentAccountName("New Account Name").to_legacy #=> "Old Account Name"
82
+
83
+ ## TODO ##
84
+
85
+ Better indexing in migrations
86
+ Rake task for installing views
87
+ Add security features
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Mappable'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rspec/core/rake_task'
30
+
31
+ RSpec::Core::RakeTask.new(:spec)
32
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,7 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,56 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ div.field, div.actions {
20
+ margin-bottom: 10px;
21
+ }
22
+
23
+ #notice {
24
+ color: green;
25
+ }
26
+
27
+ .field_with_errors {
28
+ padding: 2px;
29
+ background-color: red;
30
+ display: table;
31
+ }
32
+
33
+ #error_explanation {
34
+ width: 450px;
35
+ border: 2px solid red;
36
+ padding: 7px;
37
+ padding-bottom: 0;
38
+ margin-bottom: 20px;
39
+ background-color: #f0f0f0;
40
+ }
41
+
42
+ #error_explanation h2 {
43
+ text-align: left;
44
+ font-weight: bold;
45
+ padding: 5px 5px 5px 15px;
46
+ font-size: 12px;
47
+ margin: -7px;
48
+ margin-bottom: 0px;
49
+ background-color: #c00;
50
+ color: #fff;
51
+ }
52
+
53
+ #error_explanation ul li {
54
+ font-size: 12px;
55
+ list-style: square;
56
+ }
@@ -0,0 +1,4 @@
1
+ module Mappable
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,54 @@
1
+ module Mappable
2
+ class MappingsController < ApplicationController
3
+ before_filter :load_map!, only: [:index, :new]
4
+
5
+ def index
6
+ @mappings = @map.mappings
7
+ end
8
+
9
+ def show
10
+ @mapping = Mapping.find(params[:id])
11
+ end
12
+
13
+ def new
14
+ @mapping = Mapping.new(map: @map)
15
+ end
16
+
17
+ def edit
18
+ @mapping = Mapping.find(params[:id])
19
+ end
20
+
21
+ def create
22
+ @mapping = Mapping.new(params[:mapping])
23
+
24
+ if @mapping.save
25
+ redirect_to mappings_url(subject: @mapping.parent_map.subject, attr: @mapping.parent_map.attr.pluralize), notice: 'Mapping was successfully created.'
26
+ else
27
+ render action: "new"
28
+ end
29
+ end
30
+
31
+ def update
32
+ @mapping = Mapping.find(params[:id])
33
+
34
+ if @mapping.update_attributes(params[:mapping])
35
+ redirect_to mappings_url(subject: @mapping.parent_map.subject, attr: @mapping.parent_map.attr.pluralize), notice: 'Mapping was successfully updated.'
36
+ else
37
+ render action: "edit"
38
+ end
39
+ end
40
+
41
+ def destroy
42
+ @mapping = Mapping.find(params[:id])
43
+ @mapping.destroy
44
+
45
+ redirect_to mappings_url
46
+ end
47
+
48
+ private
49
+
50
+ def load_map!
51
+ @map = Map.find_by_subject_and_attr!(params[:subject], params[:attr].try(:singularize))
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,46 @@
1
+ module Mappable
2
+ class MapsController < ApplicationController
3
+ def index
4
+ @maps = Map.all
5
+ end
6
+
7
+ def show
8
+ @map = Map.find(params[:id])
9
+ end
10
+
11
+ def new
12
+ @map = Map.new
13
+ end
14
+
15
+ def edit
16
+ @map = Map.find(params[:id])
17
+ end
18
+
19
+ def create
20
+ @map = Map.new(params[:map])
21
+
22
+ if @map.save
23
+ redirect_to maps_url, notice: 'Map was successfully created.'
24
+ else
25
+ render action: "new"
26
+ end
27
+ end
28
+
29
+ def update
30
+ @map = Map.find(params[:id])
31
+
32
+ if @map.update_attributes(params[:map])
33
+ redirect_to maps_url, notice: 'Map was successfully updated.'
34
+ else
35
+ render action: "edit"
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ @map = Map.find(params[:id])
41
+ @map.destroy
42
+
43
+ redirect_to maps_url
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,4 @@
1
+ module Mappable
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Mappable
2
+ module MappingsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Mappable
2
+ module MapsHelper
3
+ end
4
+ end
@@ -0,0 +1,19 @@
1
+ module Mappable
2
+ class Map < ActiveRecord::Base
3
+ has_many :mappings
4
+
5
+ after_save do
6
+ Mappable::MapRouter.build_map_routes!
7
+ end
8
+
9
+ def value_for(mapping_name, in_value)
10
+ in_direction = :from if to.to_sym == mapping_name
11
+ in_direction = :to if from.to_sym == mapping_name
12
+ if in_direction
13
+ out_direction = :from if in_direction == :to
14
+ out_direction = :to if in_direction == :from
15
+ self.mappings.where(in_direction => in_value).first.send(out_direction)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ module Mappable
2
+ class Mapping < ActiveRecord::Base
3
+ belongs_to :map
4
+ belongs_to :parent_map, :foreign_key => :map_id, :class_name => :Map
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ <%= form_for(@mapping, url: mappings_url(subject: @mapping.parent_map.subject, attr: @mapping.parent_map.attr.pluralize)) do |f| %>
2
+ <% if @mapping.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@mapping.errors.count, "error") %> prohibited this mapping from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @mapping.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :from %><br />
16
+ <%= f.text_field :from %>
17
+ </div>
18
+ <div class="field">
19
+ <%= f.label :to %><br />
20
+ <%= f.text_field :to %>
21
+ </div>
22
+ <%= f.hidden_field :map_id %>
23
+ <div class="actions">
24
+ <%= f.submit %>
25
+ </div>
26
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing mapping</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @mapping %> |
6
+ <%= link_to 'Back', mappings_path %>
@@ -0,0 +1,25 @@
1
+ <h1><%= @map.subject.humanize %> <%= @map.attr.humanize.downcase %> mappings</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>From</th>
6
+ <th>To</th>
7
+ <th></th>
8
+ <th></th>
9
+ <th></th>
10
+ </tr>
11
+
12
+ <% @mappings.each do |mapping| %>
13
+ <tr>
14
+ <td><%= mapping.from %></td>
15
+ <td><%= mapping.to %></td>
16
+ <td><%= link_to 'Show', mapping_path(mapping, subject: @map.subject, attr: @map.attr.pluralize) %></td>
17
+ <td><%= link_to 'Edit', edit_mapping_path(mapping) %></td>
18
+ <td><%= link_to 'Destroy', mapping_path(mapping, subject: @map.subject, attr: @map.attr.pluralize), confirm: 'Are you sure?', method: :delete %></td>
19
+ </tr>
20
+ <% end %>
21
+ </table>
22
+
23
+ <br />
24
+
25
+ <%= link_to "New #{@map.subject.humanize.titleize} #{@map.attr.humanize.titleize} Mapping", new_mapping_path(subject: @map.subject, attr: @map.attr.pluralize) %>
@@ -0,0 +1,5 @@
1
+ <h1>New mapping</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', mappings_path(subject: @mapping.parent_map.subject, attr: @mapping.parent_map.attr) %>
@@ -0,0 +1,19 @@
1
+ <h1>Edit <%= @map.subject.humanize.titleize %> <%= @map.attr.humanize.titleize %> Mappings</h1>
2
+
3
+ <p>
4
+ <b>Map:</b>
5
+ <%= @mapping.parent_map.subject %>
6
+ </p>
7
+
8
+ <p>
9
+ <b>From:</b>
10
+ <%= @mapping.from %>
11
+ </p>
12
+
13
+ <p>
14
+ <b>To:</b>
15
+ <%= @mapping.to %>
16
+ </p>
17
+
18
+ <%= link_to 'Edit', edit_mapping_path(@mapping) %> |
19
+ <%= link_to 'Back', mappings_path %>
@@ -0,0 +1,47 @@
1
+ <%= form_for(@map) do |f| %>
2
+ <% if @map.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@map.errors.count, "error") %> prohibited this map from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @map.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <table border=0 cellpadding="0" cellspacing="5">
15
+ <tr>
16
+ <td>
17
+ <div class="field">
18
+ <%= f.label :subject %><br />
19
+ <%= f.text_field :subject %>
20
+ </div>
21
+ </td>
22
+ <td>
23
+ <div class="field">
24
+ <%= f.label :attr, "Attribute" %><br />
25
+ <%= f.text_field :attr %>
26
+ </div>
27
+ </td>
28
+ </tr>
29
+ <tr>
30
+ <td>
31
+ <div class="field">
32
+ <%= f.label :from, "From name" %><br />
33
+ <%= f.text_field :from %>
34
+ </div>
35
+ </td>
36
+ <td>
37
+ <div class="field">
38
+ <%= f.label :to, "To name" %><br />
39
+ <%= f.text_field :to %>
40
+ </div>
41
+ </td>
42
+ </tr>
43
+ </table>
44
+ <div class="actions">
45
+ <%= f.submit %>
46
+ </div>
47
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing map</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @map %> |
6
+ <%= link_to 'Back', maps_path %>
@@ -0,0 +1,29 @@
1
+ <h1>Maps</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Subject</th>
6
+ <th>Attribute</th>
7
+ <th>From</th>
8
+ <th>To</th>
9
+ <th></th>
10
+ <th></th>
11
+ <th></th>
12
+ </tr>
13
+
14
+ <% @maps.each do |map| %>
15
+ <tr>
16
+ <td><%= map.subject %></td>
17
+ <td><%= map.attr %></td>
18
+ <td><%= map.from %></td>
19
+ <td><%= map.to %></td>
20
+ <td><%= link_to 'Show', map %></td>
21
+ <td><%= link_to 'Edit', edit_map_path(map) %></td>
22
+ <td><%= link_to 'Destroy', map, confirm: 'Are you sure?', method: :delete %></td>
23
+ </tr>
24
+ <% end %>
25
+ </table>
26
+
27
+ <br />
28
+
29
+ <%= link_to 'New Map', new_map_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New map</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', maps_path %>
@@ -0,0 +1,25 @@
1
+ <h1><%= @map.subject.humanize.titleize %> <%= @map.attr.humanize.titleize %> Mappings</h1>
2
+
3
+ <h2>Maps <em><%= @map.from %></em> to <em><%= @map.to %></em></h2>
4
+
5
+ <table border="0" cellpadding="5" cellspacing="1">
6
+ <thead>
7
+ <tr>
8
+ <th>From</th>
9
+ <th>To</th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ <% @map.mappings.each do |mapping| %>
14
+ <tr>
15
+ <td><%= mapping.from %></td>
16
+ <td><%= mapping.to %></td>
17
+ </tr>
18
+ <% end %>
19
+ </tbody>
20
+ </table>
21
+
22
+ <br />
23
+
24
+ <%= link_to 'Edit', edit_map_path(@map) %> |
25
+ <%= link_to 'Back', maps_path %>
data/config/routes.rb ADDED
@@ -0,0 +1,25 @@
1
+ Mappable::Engine.routes.draw do
2
+ resources :maps, :path => "/"
3
+
4
+ match "/:subject/:attr",
5
+ to: 'mappings#index',
6
+ as: 'mappings',
7
+ via: 'get'
8
+
9
+ match "/:subject/:attr",
10
+ to: 'mappings#create',
11
+ as: 'mappings',
12
+ via: 'post'
13
+
14
+ match "/:subject/:attr/new",
15
+ to: 'mappings#new',
16
+ as: 'new_mapping',
17
+ via: 'get'
18
+
19
+ match "/:subject/:attr/:id",
20
+ to: 'mappings#show',
21
+ as: 'mapping',
22
+ via: 'get'
23
+
24
+ resources :mappings, only: [:edit, :destroy]
25
+ end
@@ -0,0 +1,12 @@
1
+ class CreateMappableMaps < ActiveRecord::Migration
2
+ def change
3
+ create_table :mappable_maps do |t|
4
+ t.string :subject
5
+ t.string :attr
6
+ t.string :from
7
+ t.string :to
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class CreateMappableMappings < ActiveRecord::Migration
2
+ def change
3
+ create_table :mappable_mappings do |t|
4
+ t.string :from
5
+ t.string :to
6
+ t.references :map
7
+
8
+ t.timestamps
9
+ end
10
+ add_index :mappable_mappings, :map_id
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ Description:
2
+ Copy the views from mappable so you can override them
3
+
4
+ Example:
5
+ rails generate mappable:views
6
+
7
+ This will create:
8
+ app/views/mappable
9
+ app/views/mappable/mappings
10
+ app/views/mappable/mappings/_form.html.erb
11
+ app/views/mappable/mappings/edit.html.erb
12
+ app/views/mappable/mappings/index.html.erb
13
+ app/views/mappable/mappings/new.html.erb
14
+ app/views/mappable/mappings/show.html.erb
15
+ app/views/mappable/maps
16
+ app/views/mappable/maps/_form.html.erb
17
+ app/views/mappable/maps/edit.html.erb
18
+ app/views/mappable/maps/index.html.erb
19
+ app/views/mappable/maps/new.html.erb
20
+ app/views/mappable/maps/show.html.erb
@@ -0,0 +1,20 @@
1
+ module Mappable
2
+ class ViewsGenerator < Rails::Generators::NamedBase
3
+ source_root File.expand_path('../../../../../app/views/mappable', __FILE__)
4
+ argument :name, :type => :string, :default => 'views'
5
+
6
+ def copy_view_files
7
+ empty_directory "app/views/mappable/maps"
8
+ copy_file "maps/_form.html.erb", "app/views/mappable/maps/_form.html.erb"
9
+ copy_file "maps/edit.html.erb", "app/views/mappable/maps/edit.html.erb"
10
+ copy_file "maps/index.html.erb", "app/views/mappable/maps/index.html.erb"
11
+ copy_file "maps/new.html.erb", "app/views/mappable/maps/new.html.erb"
12
+ copy_file "maps/show.html.erb", "app/views/mappable/maps/show.html.erb"
13
+ empty_directory "app/views/mappable/mappings"
14
+ copy_file "mappings/edit.html.erb", "app/views/mappable/mappings/edit.html.erb"
15
+ copy_file "mappings/index.html.erb", "app/views/mappable/mappings/index.html.erb"
16
+ copy_file "mappings/new.html.erb", "app/views/mappable/mappings/new.html.erb"
17
+ copy_file "mappings/show.html.erb", "app/views/mappable/mappings/show.html.erb"
18
+ end
19
+ end
20
+ end
data/lib/mappable.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "mappable/engine"
2
+ require "mappable/map_route"
3
+ require "mappable/map_router"
4
+
5
+ module Mappable
6
+ end
@@ -0,0 +1,9 @@
1
+ module Mappable
2
+ class Engine < Rails::Engine
3
+ isolate_namespace Mappable
4
+
5
+ config.to_prepare do
6
+ Mappable::MapRouter.build_map_routes!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module Mappable
2
+ class MapRoute
3
+ attr_reader :map, :in_value
4
+
5
+ def initialize(map, in_value)
6
+ @map = map
7
+ @in_value = in_value
8
+ end
9
+
10
+ def mapped_value_for_method_missing(sym)
11
+ mapping_name = sym.to_s.slice(3..-1).to_sym
12
+ map.value_for(mapping_name, in_value)
13
+ end
14
+
15
+ def map_route_method?(sym)
16
+ sym.to_s.starts_with?('to_')
17
+ end
18
+
19
+ def method_missing(sym, *args, &block)
20
+ if map_route_method?(sym)
21
+ mapped_value_for_method_missing(sym)
22
+ else
23
+ super(sym, *args, &block)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module Mappable
2
+ class MapRouter
3
+ class << self
4
+ def build_map_routes!
5
+ # this can get called before the database has been migrated
6
+ return unless Mappable::Map.table_exists?
7
+ Mappable::Map.all.each do |map|
8
+ build_map_route!(:from, map)
9
+ build_map_route!(:to, map)
10
+ end
11
+ end
12
+
13
+ def build_map_route!(direction, map)
14
+ mapping_name = map.send(direction.to_sym)
15
+ method_sym = "#{mapping_name}_#{map.subject}_#{map.attr}".camelize.to_sym
16
+ Kernel.send :define_method, method_sym do |in_value|
17
+ Mappable::MapRoute.new(map, in_value)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Mappable
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :mappable do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mappable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Bannister
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-21 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &2156013160 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2156013160
25
+ - !ruby/object:Gem::Dependency
26
+ name: sqlite3
27
+ requirement: &2156012300 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.4
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2156012300
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec-rails
38
+ requirement: &2156011300 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.6.1
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2156011300
47
+ - !ruby/object:Gem::Dependency
48
+ name: capybara
49
+ requirement: &2156010320 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.1.1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2156010320
58
+ - !ruby/object:Gem::Dependency
59
+ name: mocha
60
+ requirement: &2156009440 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.10.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2156009440
69
+ - !ruby/object:Gem::Dependency
70
+ name: launchy
71
+ requirement: &2156008220 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 2.0.5
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2156008220
80
+ description: Lightweight string mappings engine for Rails
81
+ email:
82
+ - mikebannister@gmail.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - app/assets/javascripts/mappable/application.js
88
+ - app/assets/javascripts/mappable/mappings.js
89
+ - app/assets/javascripts/mappable/maps.js
90
+ - app/assets/stylesheets/mappable/application.css
91
+ - app/assets/stylesheets/mappable/mappings.css
92
+ - app/assets/stylesheets/mappable/maps.css
93
+ - app/assets/stylesheets/scaffold.css
94
+ - app/controllers/mappable/application_controller.rb
95
+ - app/controllers/mappable/mappings_controller.rb
96
+ - app/controllers/mappable/maps_controller.rb
97
+ - app/helpers/mappable/application_helper.rb
98
+ - app/helpers/mappable/mappings_helper.rb
99
+ - app/helpers/mappable/maps_helper.rb
100
+ - app/models/mappable/map.rb
101
+ - app/models/mappable/mapping.rb
102
+ - app/views/mappable/mappings/_form.html.erb
103
+ - app/views/mappable/mappings/edit.html.erb
104
+ - app/views/mappable/mappings/index.html.erb
105
+ - app/views/mappable/mappings/new.html.erb
106
+ - app/views/mappable/mappings/show.html.erb
107
+ - app/views/mappable/maps/_form.html.erb
108
+ - app/views/mappable/maps/edit.html.erb
109
+ - app/views/mappable/maps/index.html.erb
110
+ - app/views/mappable/maps/new.html.erb
111
+ - app/views/mappable/maps/show.html.erb
112
+ - config/routes.rb
113
+ - db/migrate/20110919042052_create_mappable_maps.rb
114
+ - db/migrate/20110919042056_create_mappable_mappings.rb
115
+ - lib/generators/mappable/views/USAGE
116
+ - lib/generators/mappable/views/views_generator.rb
117
+ - lib/mappable/engine.rb
118
+ - lib/mappable/map_route.rb
119
+ - lib/mappable/map_router.rb
120
+ - lib/mappable/version.rb
121
+ - lib/mappable.rb
122
+ - lib/tasks/mappable_tasks.rake
123
+ - MIT-LICENSE
124
+ - Rakefile
125
+ - README.md
126
+ homepage: https://github.com/mikebannister/mappable
127
+ licenses: []
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ segments:
139
+ - 0
140
+ hash: 2003648880004134230
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ! '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ segments:
148
+ - 0
149
+ hash: 2003648880004134230
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 1.8.8
153
+ signing_key:
154
+ specification_version: 3
155
+ summary: Lightweight string mappings engine for Rails
156
+ test_files: []