custom_attributes_scaffold 0.1.0

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 (88) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/Rakefile +37 -0
  4. data/app/assets/javascripts/custom_attributes/application.js +13 -0
  5. data/app/assets/stylesheets/custom_attributes/application.css +15 -0
  6. data/app/controllers/custom_attributes/application_controller.rb +4 -0
  7. data/app/controllers/custom_attributes/custom_attribute_definitions_controller.rb +14 -0
  8. data/app/controllers/custom_attributes/custom_attribute_values_controller.rb +16 -0
  9. data/app/models/custom_attributes/custom_attribute.rb +11 -0
  10. data/app/models/custom_attributes/custom_attribute_definition.rb +10 -0
  11. data/app/models/custom_attributes/custom_attribute_value.rb +12 -0
  12. data/app/models/custom_attributes/date_time_value.rb +15 -0
  13. data/app/models/custom_attributes/double_value.rb +15 -0
  14. data/app/models/custom_attributes/integer_value.rb +15 -0
  15. data/app/models/custom_attributes/string_value.rb +15 -0
  16. data/app/views/custom_attributes/custom_attribute_definitions/_form.html.erb +27 -0
  17. data/app/views/custom_attributes/custom_attribute_definitions/_form_fields_only.html.erb +12 -0
  18. data/app/views/custom_attributes/custom_attribute_definitions/_show.html.erb +16 -0
  19. data/app/views/custom_attributes/custom_attribute_values/_custom_attribute_value.html.erb +15 -0
  20. data/app/views/custom_attributes/date_time_values/_edit_date_time_value.html.erb +25 -0
  21. data/app/views/custom_attributes/date_time_values/_show_date_time_value.html.erb +8 -0
  22. data/app/views/custom_attributes/double_values/_edit_double_value.html.erb +25 -0
  23. data/app/views/custom_attributes/double_values/_show_double_value.html.erb +8 -0
  24. data/app/views/custom_attributes/integer_values/_edit_integer_value.html.erb +25 -0
  25. data/app/views/custom_attributes/integer_values/_show_integer_value.html.erb +8 -0
  26. data/app/views/custom_attributes/string_values/_edit_string_value.html.erb +33 -0
  27. data/app/views/custom_attributes/string_values/_show_string_value.html.erb +7 -0
  28. data/app/views/layouts/custom_attributes/application.html.erb +14 -0
  29. data/config/routes.rb +2 -0
  30. data/lib/custom_attributes/engine.rb +5 -0
  31. data/lib/custom_attributes/setup.rb +13 -0
  32. data/lib/custom_attributes/version.rb +3 -0
  33. data/lib/custom_attributes.rb +45 -0
  34. data/lib/generators/custom_attributes/initialize_generator.rb +77 -0
  35. data/lib/generators/custom_attributes/templates/application_helper.rb +14 -0
  36. data/lib/generators/custom_attributes/templates/custom_attribute_definition_model.rb +17 -0
  37. data/lib/generators/custom_attributes/templates/custom_attribute_definitions_controller.rb +36 -0
  38. data/lib/generators/custom_attributes/templates/custom_attribute_value_model.rb +31 -0
  39. data/lib/generators/custom_attributes/templates/custom_attribute_value_sub_class.html.erb +9 -0
  40. data/lib/generators/custom_attributes/templates/custom_attribute_value_sub_class_model.rb +3 -0
  41. data/lib/generators/custom_attributes/templates/custom_attribute_values_controller.rb +9 -0
  42. data/lib/generators/custom_attributes/templates/custom_attributes_concern.rb +43 -0
  43. data/lib/generators/custom_attributes/templates/custom_attributes_inline_editing.js.erb +45 -0
  44. data/lib/generators/custom_attributes/templates/migration.rb +38 -0
  45. data/lib/generators/custom_attributes/templates/view.html.erb +16 -0
  46. data/lib/tasks/custom_attributes_tasks.rake +4 -0
  47. data/test/custom_attributes_test.rb +7 -0
  48. data/test/dummy/README.rdoc +28 -0
  49. data/test/dummy/Rakefile +6 -0
  50. data/test/dummy/app/assets/javascripts/application.js +13 -0
  51. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  52. data/test/dummy/app/controllers/application_controller.rb +5 -0
  53. data/test/dummy/app/helpers/application_helper.rb +2 -0
  54. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  55. data/test/dummy/bin/bundle +3 -0
  56. data/test/dummy/bin/rails +4 -0
  57. data/test/dummy/bin/rake +4 -0
  58. data/test/dummy/bin/setup +29 -0
  59. data/test/dummy/config/application.rb +26 -0
  60. data/test/dummy/config/boot.rb +5 -0
  61. data/test/dummy/config/database.yml +25 -0
  62. data/test/dummy/config/environment.rb +5 -0
  63. data/test/dummy/config/environments/development.rb +41 -0
  64. data/test/dummy/config/environments/production.rb +79 -0
  65. data/test/dummy/config/environments/test.rb +42 -0
  66. data/test/dummy/config/initializers/assets.rb +11 -0
  67. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  68. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  69. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  70. data/test/dummy/config/initializers/inflections.rb +16 -0
  71. data/test/dummy/config/initializers/mime_types.rb +4 -0
  72. data/test/dummy/config/initializers/session_store.rb +3 -0
  73. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  74. data/test/dummy/config/locales/en.yml +23 -0
  75. data/test/dummy/config/routes.rb +4 -0
  76. data/test/dummy/config/secrets.yml +22 -0
  77. data/test/dummy/config.ru +4 -0
  78. data/test/dummy/public/404.html +67 -0
  79. data/test/dummy/public/422.html +67 -0
  80. data/test/dummy/public/500.html +66 -0
  81. data/test/dummy/public/favicon.ico +0 -0
  82. data/test/fixtures/custom_attributes/custom_attribute_values.yml +11 -0
  83. data/test/fixtures/custom_attributes/custom_attributes.yml +9 -0
  84. data/test/integration/navigation_test.rb +10 -0
  85. data/test/models/custom_attributes/custom_attribute_test.rb +9 -0
  86. data/test/models/custom_attributes/custom_attribute_value_test.rb +9 -0
  87. data/test/test_helper.rb +20 -0
  88. metadata +200 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 98a26dfe77e52e5f1a730d9982b56cc810306962
4
+ data.tar.gz: 7c106f5c947d730388f74830951f81406f361d3f
5
+ SHA512:
6
+ metadata.gz: a7c566e5684e35b8f66898eba661d427311366c63ebaa27167b1336f0ba856762745e3cdf49d51a29dcb0a14aa9740260a127f00cc7f8c55992e19dcbfbaf790
7
+ data.tar.gz: b96c49af1c211725ba7c8cb6716f1579754438966085fe82a4942b2bb5f93f2363726b25cf43e2edb056883d5d5c3dc8839144eb1ed0a830ad653833b1214662
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 7Vals
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/Rakefile ADDED
@@ -0,0 +1,37 @@
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
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'CustomAttributes'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task default: :test
@@ -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,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module CustomAttributes
2
+ class ApplicationController < ::ApplicationController
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ module CustomAttributes
2
+ class CustomAttributeDefinitionsController < ApplicationController
3
+
4
+ def index
5
+ @custom_attributes = custom_attributes_scope.all
6
+ end
7
+
8
+ def new
9
+ @custom_attribute = custom_attributes_scope.new
10
+ @custom_attribute.sort_order = custom_attributes_scope.size() + 1
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module CustomAttributes
2
+ class CustomAttributeValuesController < ApplicationController
3
+ def create
4
+ ca = @owner.custom_attributes.find {|ca| ca.name==params[:name]}
5
+
6
+ respond_to do |format|
7
+ ca.value = params[:value]
8
+ if ca.save
9
+ format.json { render json: ca.to_json(methods: :value), status: :created }
10
+ else
11
+ format.json { render json: ca, status: :unprocessable_entity }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module CustomAttributes
2
+ #TODO: Move this class since this is not a model
3
+ class CustomAttribute
4
+ TYPE_NUMBER = 'number'
5
+ TYPE_DECIMAL = 'decimal'
6
+ TYPE_TEXT = 'text'
7
+ TYPE_MULTILINE_TEXT = 'multiline_text'
8
+ TYPE_DATE = 'date'
9
+ TYPE_DATE_TIME = 'date_time'
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module CustomAttributes
2
+ module CustomAttributeDefinition
3
+ extend ActiveSupport::Concern
4
+ included do
5
+
6
+ # For future additions to the custom attribute defintion functionality
7
+
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ module CustomAttributes
2
+ module CustomAttributeValue
3
+ extend ActiveSupport::Concern
4
+ included do
5
+
6
+ def name
7
+ custom_attribute_defn.attr_name
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module CustomAttributes
2
+ module DateTimeValue
3
+ def value=(newVal)
4
+ if (newVal && newVal.present?)
5
+ self.date_time_value = Date.parse(newVal)
6
+ else
7
+ self.date_time_value = nil
8
+ end
9
+ end
10
+
11
+ def value
12
+ self.date_time_value
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CustomAttributes
2
+ module DoubleValue
3
+ def value=(newVal)
4
+ if (newVal && newVal.present?)
5
+ self.double_value = newVal.to_f
6
+ else
7
+ self.integer_value = nil
8
+ end
9
+ end
10
+
11
+ def value
12
+ self.double_value
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CustomAttributes
2
+ module IntegerValue
3
+ def value=(newVal)
4
+ if (newVal && newVal.present?)
5
+ self.integer_value = newVal.to_i
6
+ else
7
+ self.integer_value = nil
8
+ end
9
+ end
10
+
11
+ def value
12
+ self.integer_value
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CustomAttributes
2
+ module StringValue
3
+ def value=(newVal)
4
+ if (newVal && newVal.present?)
5
+ self.string_value = newVal
6
+ else
7
+ self.string_value = nil
8
+ end
9
+ end
10
+
11
+ def value
12
+ self.string_value
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ <%= form_for(@custom_attribute) do |f| %>
2
+ <% if @custom_attribute.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@custom_attribute.errors.count, "error") %> prohibited this custom attribute from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @custom_attribute.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ Name: <%= f.text_field :attr_name %>
16
+ </div>
17
+ <div class="field">
18
+ Type: <%= f.text_field :attr_type %>
19
+ </div>
20
+ <div class="field">
21
+ Sort Order: <%= f.text_field :sort_order %>
22
+ </div>
23
+
24
+ <div class="actions">
25
+ <%= f.submit %>
26
+ </div>
27
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <% new_record ||= false %>
2
+ <div class="custom-attribute-definition title">Name:</div>
3
+ <div class="custom-attribute-definition field">
4
+ <%= f.text_field :attr_name, pattern:"^[a-zA-Z0-9\_\s]+$", title: "Name can only contain alphanumeric characters and spaces." %></div>
5
+
6
+ <div class="custom-attribute-definition title">Type:</div>
7
+ <div class="custom-attribute-definition field">
8
+ <%= f.select :attr_type, custom_attribute_types.invert, {}, {disabled: !new_record}%>
9
+ </div>
10
+
11
+ <div class="custom-attribute-definition title">Sort Order:</div>
12
+ <div class="custom-attribute-definition field"><%= f.text_field :sort_order, readonly: true%></div>
@@ -0,0 +1,16 @@
1
+ <% cssClasses ||= {} %>
2
+
3
+ <div class="custom-attributes row">
4
+ <div class="custom-attributes definition title <%=cssClasses[:title]%>">
5
+ <%= custom_attribute_definition.attr_name %>
6
+ </div>
7
+ <div class="custom-attributes definition field <%=cssClasses[:field]%>">
8
+ <% if custom_attribute_definition.attr_type == CustomAttributes::CustomAttribute::TYPE_TEXT %>
9
+ <input type="text" disabled="disabled">
10
+ <% elsif custom_attribute_definition.attr_type == CustomAttributes::CustomAttribute::TYPE_MULTILINE_TEXT %>
11
+ <textarea disabled="disabled"></textarea>
12
+ <% else %>
13
+ <input type="text" disabled="disabled">
14
+ <% end %>
15
+ </div>
16
+ </div>
@@ -0,0 +1,15 @@
1
+ <% editable ||= false %>
2
+
3
+ <br/>
4
+ <% if not editable %>
5
+ <%= custom_attribute_value.name %>: <%= custom_attribute_value.value %>
6
+ <% else %>
7
+ <%= form.fields_for :custom_attributes do |custom_fields| %>
8
+ <%= custom_attribute_value.name %><br/>
9
+ <% if custom_attribute_value.custom_attribute.attr_type==CustomAttributes::CustomAttribute::TYPE_MULTILINE_TEXT %>
10
+ <%= custom_fields.text_area "#{custom_attribute_value.name}".to_sym, :value=>"#{custom_attribute_value.value}" %>
11
+ <% else %>
12
+ <%= custom_fields.text_field "#{custom_attribute_value.name}".to_sym, :value=>"#{custom_attribute_value.value}" %>
13
+ <% end %>
14
+ <% end %>
15
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <% form ||= nil %>
2
+ <% cssClasses ||= {} %>
3
+
4
+ <% if form %>
5
+ <% # BEGIN Field part of form %>
6
+ <%= form.fields_for :custom_attributes do |custom_fields| %>
7
+ <%= date_time_value.name %><br/>
8
+ <%= custom_fields.text_field "#{date_time_value.name}".to_sym, :value=>"#{date_time_value.value}" %>
9
+ <% end %>
10
+ <% # END Field part of form %>
11
+ <% else %>
12
+ <% # BEGIN Inline Editing %>
13
+ <div class="custom-attributes editable-inline" data-controller="<%= date_time_value.owner.class.to_s.underscore %>_custom_attribute_values" data-owner-id="<%= date_time_value.owner.id %>" data-attr-name="<%= date_time_value.name %>">
14
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
15
+ <%= date_time_value.name %>
16
+ </div>
17
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
18
+ <%= date_time_value.value %>
19
+ </div>
20
+ <div class="custom-attributes field datetime <%=cssClasses[:field]%>" style="display: none">
21
+ <input type="text" class="custom-attributes field" value="<%= date_time_value.value %>"/>
22
+ </div>
23
+ </div>
24
+ <% # END Inline Editing %>
25
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <% cssClasses ||= {} %>
2
+
3
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
4
+ <%= date_time_value.name %>
5
+ </div>
6
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
7
+ <%= date_time_value.value %>
8
+ </div>
@@ -0,0 +1,25 @@
1
+ <% form ||= nil %>
2
+ <% cssClasses ||= {} %>
3
+
4
+ <% if form %>
5
+ <% # BEGIN Field part of form %>
6
+ <%= form.fields_for :custom_attributes do |custom_fields| %>
7
+ <%= double_value.name %><br/>
8
+ <%= custom_fields.text_field "#{double_value.name}".to_sym, :value=>"#{double_value.value}" %>
9
+ <% end %>
10
+ <% # END Field part of form %>
11
+ <% else %>
12
+ <% # BEGIN Inline Editing %>
13
+ <div class="custom-attributes editable-inline" data-controller="<%= double_value.owner.class.to_s.underscore %>_custom_attribute_values" data-owner-id="<%= double_value.owner.id %>" data-attr-name="<%= double_value.name %>">
14
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
15
+ <%= double_value.name %>
16
+ </div>
17
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
18
+ <%= double_value.value %>
19
+ </div>
20
+ <div class="custom-attributes field <%=cssClasses[:field]%>" style="display: none">
21
+ <input type="text" pattern="[0-9]+(\.[0-9]+)?" class="custom-attributes field" value="<%= double_value.value %>"/>
22
+ </div>
23
+ </div>
24
+ <% # END Inline Editing %>
25
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <% cssClasses ||= {} %>
2
+
3
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
4
+ <%= double_value.name %>
5
+ </div>
6
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
7
+ <%= double_value.value %>
8
+ </div>
@@ -0,0 +1,25 @@
1
+ <% form ||= nil %>
2
+ <% cssClasses ||= {} %>
3
+
4
+ <% if form %>
5
+ <% # BEGIN Field part of form %>
6
+ <%= form.fields_for :custom_attributes do |custom_fields| %>
7
+ <%= integer_value.name %><br/>
8
+ <%= custom_fields.text_field "#{integer_value.name}".to_sym, :value=>"#{integer_value.value}" %>
9
+ <% end %>
10
+ <% # END Field part of form %>
11
+ <% else %>
12
+ <% # BEGIN Inline Editing %>
13
+ <div class="custom-attributes editable-inline" data-controller="<%= integer_value.owner.class.to_s.underscore %>_custom_attribute_values" data-owner-id="<%= integer_value.owner.id %>" data-attr-name="<%= integer_value.name %>">
14
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
15
+ <%= integer_value.name %>
16
+ </div>
17
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
18
+ <%= integer_value.value %>
19
+ </div>
20
+ <div class="custom-attributes field <%=cssClasses[:field]%>" style="display: none">
21
+ <input type="text" pattern="[0-9]+" class="custom-attributes field" value="<%= integer_value.value %>"/>
22
+ </div>
23
+ </div>
24
+ <% # END Inline Editing %>
25
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <% cssClasses ||= {} %>
2
+
3
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
4
+ <%= integer_value.name %>
5
+ </div>
6
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
7
+ <%= integer_value.value %>
8
+ </div>
@@ -0,0 +1,33 @@
1
+ <% form ||= nil %>
2
+ <% cssClasses ||= {} %>
3
+
4
+ <% if form %>
5
+ <% # BEGIN Field part of form %>
6
+ <%= form.fields_for :custom_attributes do |custom_fields| %>
7
+ <%= string_value.name %><br/>
8
+ <% if string_value.custom_attribute_defn.attr_type==CustomAttributes::CustomAttribute::TYPE_MULTILINE_TEXT %>
9
+ <%= custom_fields.text_area "#{string_value.name}".to_sym, :value=>"#{string_value.value}" %>
10
+ <% else %>
11
+ <%= custom_fields.text_field "#{string_value.name}".to_sym, :value=>"#{string_value.value}" %>
12
+ <% end %>
13
+ <% end %>
14
+ <% # END Field part of form %>
15
+ <% else %>
16
+ <% # BEGIN Inline Editing %>
17
+ <div class="custom-attributes editable-inline" data-controller="<%= string_value.owner.class.to_s.underscore %>_custom_attribute_values" data-owner-id="<%= string_value.owner.id %>" data-attr-name="<%= string_value.name %>">
18
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
19
+ <%= string_value.name %>
20
+ </div>
21
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
22
+ <%= string_value.value %>
23
+ </div>
24
+ <div class="custom-attributes field <%=cssClasses[:field]%>" style="display: none">
25
+ <% if string_value.custom_attribute_defn.attr_type == CustomAttributes::CustomAttribute::TYPE_MULTILINE_TEXT %>
26
+ <textarea class="custom-attributes field"><%= string_value.value %></textarea>
27
+ <% else %>
28
+ <input type="text" class="custom-attributes field" value="<%= string_value.value %>"/>
29
+ <% end %>
30
+ </div>
31
+ </div>
32
+ <% # END Inline Editing %>
33
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <% cssStyles ||= {} %>
2
+ <div class="custom-attributes title <%=cssClasses[:title]%>">
3
+ <%= string_value.name %>
4
+ </div>
5
+ <div class="custom-attributes value edit-cursor <%=cssClasses[:field]%>">
6
+ <%= string_value.value %>
7
+ </div>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>CustomAttributes</title>
5
+ <%= stylesheet_link_tag "custom_attributes/application", media: "all" %>
6
+ <%= javascript_include_tag "custom_attributes/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ CustomAttributes::Engine.routes.draw do
2
+ end
@@ -0,0 +1,5 @@
1
+ module CustomAttributes
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace CustomAttributes
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module CustomAttributes
2
+ module Setup
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def allows_custom_attributes
9
+ include CustomAttributes
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module CustomAttributes
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,45 @@
1
+ require "custom_attributes/engine"
2
+ require "custom_attributes/setup"
3
+
4
+ module CustomAttributes
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_many :custom_attribute_values, :as => :owner, :class_name => 'CustomAttributes::CustomAttributeValue', autosave: true
9
+
10
+ def custom_attributes=(map_of_custom_attributes)
11
+ map_of_custom_attributes.each do |key, value|
12
+ custom_attribute_value = custom_attribute_values.find { |cav| cav.name==key }
13
+ if not custom_attribute_value
14
+ custom_attribute = self.class.allowed_custom_attributes.find { |ca| ca.attr_name == key }
15
+ #TODO: Reuse the .new method below. Also change it to a Factory like pattern
16
+ custom_attribute_value = CustomAttributeValue.new(custom_attribute: custom_attribute)
17
+ self.custom_attribute_values.push(custom_attribute_value)
18
+ end
19
+ custom_attribute_value.value = value
20
+ end
21
+ end
22
+
23
+ def custom_attributes
24
+ custom_attribute_defns = self.class.allowed_custom_attributes
25
+ custom_attribute_defns.collect { |defn|
26
+ custom_attribute_values.find { |cv| cv.custom_attribute==defn } || CustomAttributeValue.new(custom_attribute: defn)
27
+ }
28
+ end
29
+ end
30
+
31
+ module ClassMethods
32
+ def allowed_custom_attributes
33
+ #TODO: rename owner_class to owner_type
34
+ CustomAttribute.where(owner_class: self)
35
+ end
36
+
37
+ def add_allowed_custom_attribute
38
+
39
+ end
40
+ end
41
+ end
42
+
43
+ ActiveSupport.on_load(:active_record) do
44
+ include CustomAttributes::Setup
45
+ end
@@ -0,0 +1,77 @@
1
+ require 'rails/generators'
2
+
3
+ module CustomAttributes
4
+ module Generators
5
+ class InitializeGenerator < Rails::Generators::NamedBase
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path("../templates", __FILE__)
9
+ class_option :tenant, default: false
10
+
11
+ def self.next_migration_number(path)
12
+ unless @prev_migration_nr
13
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
14
+ else
15
+ @prev_migration_nr += 1
16
+ end
17
+ @prev_migration_nr.to_s
18
+ end
19
+
20
+ def create_views_and_helpers
21
+ #TODO: verify if all views are being copied
22
+ template "view.html.erb", "app/views/#{file_name}_custom_attribute_values/_#{file_name}_custom_attribute.html.erb"
23
+
24
+ #TODO: there should be a way that does NOT require copying the helper
25
+ template "application_helper.rb", "app/helpers/custom_attributes/custom_attributes_helper.rb"
26
+ end
27
+
28
+ def create_base_models
29
+ template "custom_attribute_definition_model.rb", "app/models/#{file_name}_custom_attribute_definition.rb"
30
+ template "custom_attribute_value_model.rb", "app/models/#{file_name}_custom_attribute_value.rb"
31
+ end
32
+
33
+ def create_controllers
34
+ template "custom_attribute_definitions_controller.rb", "app/controllers/#{file_name}_custom_attribute_definitions_controller.rb"
35
+ template "custom_attribute_values_controller.rb", "app/controllers/#{file_name}_custom_attribute_values_controller.rb"
36
+ end
37
+
38
+ def create_derived_custom_attribute_values
39
+ create_custom_attribute_value_sub_class("String")
40
+ create_custom_attribute_value_sub_class("Integer")
41
+ create_custom_attribute_value_sub_class("Double")
42
+ create_custom_attribute_value_sub_class("DateTime")
43
+ end
44
+
45
+ def copy_inline_editing_js_file
46
+ template "custom_attributes_inline_editing.js.erb", "public/javascripts/vendors/custom_attributes/inline_editing.js"
47
+ end
48
+
49
+ def create_migrations
50
+ migration_template "migration.rb", "db/migrate/create_custom_attributes_for_#{file_name}.rb"
51
+ end
52
+
53
+ def create_custom_attribute_concern
54
+ template "custom_attributes_concern.rb", "app/models/concerns/#{file_name}_custom_attributes.rb"
55
+ end
56
+
57
+ def include_concern_in_model
58
+ #TODO: Is this fool-proof?
59
+ inject_into_file "app/models/#{file_name}.rb", after: "ActiveRecord::Base\n" do <<-BLOCK.gsub(/^ {4}/, '')
60
+ include #{name}CustomAttributes
61
+ BLOCK
62
+ end
63
+ end
64
+
65
+ def sub_class
66
+ @sub_class
67
+ end
68
+
69
+ private
70
+ def create_custom_attribute_value_sub_class (sub_class)
71
+ @sub_class = sub_class
72
+ template "custom_attribute_value_sub_class_model.rb", "app/models/#{file_name}_custom_attribute_#{sub_class.underscore}_value.rb"
73
+ template "custom_attribute_value_sub_class.html.erb", "app/views/#{file_name}_custom_attribute_#{sub_class.underscore}_values/_#{file_name}_custom_attribute_#{sub_class.underscore}_value.html.erb"
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,14 @@
1
+ module CustomAttributes
2
+ module CustomAttributesHelper
3
+ def custom_attribute_types
4
+ types = {
5
+ CustomAttribute::TYPE_NUMBER => "Number",
6
+ CustomAttribute::TYPE_DECIMAL => "Decimal",
7
+ # CustomAttribute::TYPE_DATE => "Date",
8
+ # CustomAttribute::TYPE_DATE_TIME => "Date Time",
9
+ CustomAttribute::TYPE_TEXT => "Single Line Text",
10
+ CustomAttribute::TYPE_MULTILINE_TEXT => "Paragraph Text"
11
+ }
12
+ end
13
+ end
14
+ end