aeonscope-btech_rest 0.4.4 → 0.5.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.
data/CHANGELOG.rdoc CHANGED
@@ -21,12 +21,19 @@
21
21
  * Shortened the gem summary and added a more detailed description.
22
22
  * Updated the README file with minor setup and usage clarifications.
23
23
 
24
- = v0.4.x
24
+ = v0.5.0
25
25
 
26
26
  * Synchronized the summary and descriptions for the gem, README, and GitHub data.
27
27
  * Added UJS support for nested new/edit actions.
28
28
  * Added UJS support for nested delete actions.
29
29
  * Changed the show_destroy_link helper so that the default link ID is suffixed with "_destroy" instead of "_link".
30
- * Added a build_dom_id helper. Works the same as the dom_id found in Rails except that new records return a '_0' suffix instead of a "new_" prefix.
30
+ * Added a build_dom_id helper. Works the same as the dom_id found in Rails except that new records return a '_0' suffix instead of a "new_" prefix easier JavaScript manipulation.
31
31
  * Updated the show_destroy_link helper so that when a url option is not supplied an anchor link is used instead (derived from the record ID).
32
32
  * Updated all edit and destroy resource helpers so that they accept the parent DOM ID for which to apply UJS manipulation too.
33
+ * Renamed the rest_setup generator to ujs_setup since this is more specific.
34
+ * Changed all JavaScript code to JavaScript coding standards instead of Ruby standards (sorry, always thinking about Ruby instead ;-)
35
+ * Fixed a bug where an error would be thrown when attempting to increment null text.
36
+ * Renamed the build_action_label helper to show_action_label and removed the singularization the label passed in.
37
+ * Deleted the build_resource_form_submit helper since Rails 2.3 makes it so much easier to parse nested resource forms.
38
+ * Improved the README documentation including examples for how you might write your view code.
39
+
data/README.rdoc CHANGED
@@ -44,9 +44,9 @@ Update your environment.rb file to include the new gem:
44
44
 
45
45
  * config.gem "btech_rest"
46
46
 
47
- Type the following from the command line to setup:
47
+ To apply unobtrusive jQuery support, run the following generator (TIP: suffix the command line with -h option for usage):
48
48
 
49
- * script/generate rest_setup
49
+ * script/generate ujs_setup
50
50
 
51
51
  = Usage
52
52
 
@@ -60,6 +60,61 @@ Example:
60
60
  include BTech::Rest
61
61
  end
62
62
 
63
+ This will automatically create the seven REST actions (index, show, new, create, edit, update, and destroy) for your controller. The model (i.e. Post) and model instance (i.e. @posts or @post depending on the action) are automatically determined from the controller name and created for you as well which means you can immediately write the following code in your views:
64
+
65
+ *index.html.erb*
66
+
67
+ <h2>Posts</h2>
68
+ <div>
69
+ <table>
70
+ <thead>
71
+ <tr>
72
+ <th>Label</th>
73
+ <th>Created At</th>
74
+ <th>Updated At</th>
75
+ <th>Actions</th>
76
+ </tr>
77
+ </thead>
78
+ <tbody>
79
+ <%= render @posts %>
80
+ </tbody>
81
+ </table>
82
+ </div>
83
+
84
+ *show.html.erb*
85
+
86
+ <h2>Label</h2>
87
+ <p><%= @post.label %></p>
88
+
89
+ <h2>Content</h2>
90
+ <p><%= @post.content %></p>
91
+
92
+ <p><%= link_to "Back", :back %></p>
93
+
94
+ *new.html.erb*
95
+
96
+ <% form_for @post do |form| %>
97
+ <%= form.error_messages :header_data => :strong, :header_message => "Error" %>
98
+
99
+ <div>
100
+ <%= form.label :label %><br/>
101
+ <%= form.text_field :label %>
102
+ </div>
103
+
104
+ <div>
105
+ <%= form.label :content %><br/>
106
+ <%= form.text_area :content %>
107
+ </div>
108
+
109
+ <div><%= show_submit_and_cancel :cancel_options => posts_path %></div>
110
+ <% end %>
111
+
112
+ *edit.html.erb*
113
+
114
+ Use the same code as shown in the new.html.erb view above. ;-) The Rails form_for helper will automatically determine what action to take as shown in the following code:
115
+
116
+ <% form_for @post do |form| %>
117
+
63
118
  To customize the RESTful behavior of your controller, use any combination of these three macros:
64
119
 
65
120
  * *belongs_to* - Enables resource nesting where a controller can belong to a parent controller. This behavior is similar to the ActiveRecord {belongs_to}[http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/belongs_to] macro.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :minor: 4
3
- :patch: 4
2
+ :minor: 5
3
+ :patch: 0
4
4
  :major: 0
data/lib/actions.rb CHANGED
@@ -140,9 +140,9 @@ module BTech
140
140
  # Accepts the following argruments:
141
141
  # * *full_name* - The fully namespaced controller (i.e. PostsController) or parent name (i.e. protected_pages).
142
142
  # Usage:
143
- # * Input: Public::PostsController, Output: [Public], "PostsController"
144
- # * Input: member_manage_posts, Output: [Member, Manage], "PostsController"
145
- # * Input: posts, Output: nil, "PostsController"
143
+ # * Input: Public::PostsController, Output: [Public], "PostsController"
144
+ # * Input: member_manage_posts, Output: [Member, Manage], "PostsController"
145
+ # * Input: posts, Output: nil, "PostsController"
146
146
  def get_controller_namespaces_and_name full_name
147
147
  if full_name
148
148
  delimiter = full_name.include?("Controller") ? "::" : '_'
data/lib/class_methods.rb CHANGED
@@ -29,8 +29,7 @@ module BTech
29
29
  # Allows one to disable any number of default actions. Accepts the following parameters:
30
30
  # * *actions* - A variable list of REST action symbols you wish to disable. You may use any of the following: index, show, new, create, edit, update, and/or destroy.
31
31
  def disabled_actions *actions
32
- actions.uniq!
33
- actions.each {|action| undef_method(action)}
32
+ actions.uniq!.each {|action| undef_method action}
34
33
  end
35
34
  end
36
35
  end
@@ -24,33 +24,16 @@ module ResourceHelper
24
24
  end
25
25
 
26
26
  # Builds a DOM ID for a given record. Works the same as the dom_id helper found in Rails except that it returns a record ID with
27
- # a "_0" suffix for new records instead of a "new_" prefix.
27
+ # a "_0" suffix for new records instead of a "new_" prefix. This makes attaching JavaScript events easier since all DOM IDs are numbers.
28
28
  def build_dom_id record
29
29
  name = record.class.name.underscore
30
30
  record.new_record? ? name + "_0" : name + '_' + record.id.to_s
31
31
  end
32
32
 
33
- # Builds the submit path for a new or edit form based on current controller action. This assumes
34
- # that the new/create and edit/update forms are always submitted to the same URL. Accepts the following parameters:
35
- # * *resources* - The array of resource hashes.
36
- # * *html_options* - The html options for a form (same as form_for[http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for] html options).
37
- def build_resource_form_submit resources = [], html_options = {}
38
- case params[:action]
39
- # New/create flow.
40
- when "new" then return :url => build_resource_url(resources, :create), :html => html_options
41
- # Validate/create flow.
42
- when "create" then return :url => build_resource_url(resources, :create), :html => html_options
43
- # Edit/update flow.
44
- when "edit" then return :url => build_resource_url(resources, :update), :html => html_options.merge({:method => :put})
45
- # Validate/update flow.
46
- when "update" then return :url => build_resource_url(resources, :update), :html => html_options.merge({:method => :put})
47
- end
48
- end
49
-
50
- # Builds a more descriptive label based on the current controller action. Accepts the following parameters:
33
+ # Show a descriptive label based on the current controller action. Useful for new/edit actions. Accepts the following parameters:
51
34
  # * *label* - The action label.
52
- def build_action_label label
53
- [params[:action].capitalize, label.singularize].compact.join ' '
35
+ def show_action_label label
36
+ [params[:action].capitalize, label].compact.join ' '
54
37
  end
55
38
 
56
39
  # Shows an unobtrusive jQuery link where the UJS event is attached to the link via the "destroy" class.
@@ -76,8 +59,8 @@ module ResourceHelper
76
59
  # Shows an unobtrusive jQuery link based on an array of resource hashes. See the show_destroy_link above
77
60
  # for further details. Accepts the following arguments:
78
61
  # * *resources* - The array of resource hashes.
79
- def show_nested_destroy_resource_link resources, parent_dom_id
80
- show_destroy_link(:id => parent_dom_id.to_s + "_nested-destroy", :class => "nested-destroy") unless resources.last[:record].new_record?
62
+ def show_destroy_nested_resource_link resources, parent_dom_id
63
+ show_destroy_link(:id => parent_dom_id.to_s + "_destroy-nested", :class => "destroy-nested") unless resources.last[:record].new_record?
81
64
  end
82
65
 
83
66
  # Shows edit and delete links for resources. Accepts the following parameters:
@@ -0,0 +1,11 @@
1
+ Berserk Technologies UJS Setup Generator
2
+
3
+ Description:
4
+ Applies unobtrusive jQuery support to your Ruby on Rails application.
5
+
6
+ Requirements
7
+ 1. jQuery 1.3 or higher.
8
+ 2. jQuery UI 1.7 or higher.
9
+
10
+ Usage:
11
+ script/generate ujs_setup
@@ -1,7 +1,4 @@
1
1
 
2
- Overview
3
- REST setup is complete.
4
-
5
2
  Tasks You Need to Complete:
6
3
  1. Update your layouts/application.html.erb as follows:
7
4
 
@@ -0,0 +1,6 @@
1
+ # Enables dynamic javascript, namely Unobtrusive JavaScript (UJS) support for jQuery.
2
+ class JavascriptsController < ApplicationController
3
+ # Serves global jQuery UJS settings. See the /views/layouts/application.html.erb for usage.
4
+ def ujs
5
+ end
6
+ end
@@ -0,0 +1,119 @@
1
+ // Chops off the last string segment designated by delimiter. If no delimiter is found then the original string is
2
+ // returned instead. The following attributes are accepted:
3
+ // string = Required. The string to chop.
4
+ // delimiter = Optional. The delimiter used to chop up the string. Defaults to '_'.
5
+ function stringChop(string, delimiter) {
6
+ var chopped = string;
7
+ if (delimiter == undefined) {delimiter = '_';}
8
+ var endIndex = string.lastIndexOf(delimiter);
9
+ if (endIndex > 1) {chopped = string.slice(0, endIndex);}
10
+ return chopped;
11
+ };
12
+
13
+ // Increments a number embedded in the text by one. If no number is found then the original text is returned.
14
+ function incrementText(text) {
15
+ if (text != undefined) {
16
+ var match = text.match(/\d+/);
17
+ if (match != null) {
18
+ var number = new Number(match);
19
+ var newNumber = number + 1;
20
+ text = text.replace(number, newNumber);
21
+ }
22
+ }
23
+ return text;
24
+ };
25
+
26
+ // Increments the input field ID number by one so ActiveRecord can save new record attributes.
27
+ function incrementInputId(input) {
28
+ id = $(input).attr("id");
29
+ id = incrementText(id);
30
+ $(input).attr("id", id);
31
+ };
32
+
33
+ // Increments the input field name number by one so ActiveRecord can save new record attributes.
34
+ function incrementInputName(input) {
35
+ name = $(input).attr("name");
36
+ name = incrementText(name);
37
+ $(input).attr("name", name);
38
+ };
39
+
40
+ // Generates a hidden input field based off original input field data that instructs ActiveRecord to delete
41
+ // a record based on the ID of the input field.
42
+ function generateDestroyInput(input) {
43
+ $(input).attr("id", stringChop($(input).attr("id")) + "__delete");
44
+ $(input).attr("name", stringChop($(input).attr("name"), '[') + "[_delete]");
45
+ $(input).attr("type", "hidden");
46
+ $(input).attr("value", 1);
47
+ return input;
48
+ };
49
+
50
+ // Animates the removal of a DOM element.
51
+ function animateDestroy(id) {
52
+ $(id).animate({backgroundColor: "#FF0000", border: "0.2em solid #FF0000"}, 500);
53
+ $(id).fadeOut(500);
54
+ };
55
+
56
+ // UJS
57
+ $(document).ready(function(){
58
+ // Nested New
59
+ $("a.new-nested").click(function(){
60
+ var parentId = '#' + stringChop($(this).attr("id"));
61
+ var child = $(parentId).children(":last").clone(true);
62
+ var childId = child.attr("id");
63
+ child.attr("id", incrementText(childId));
64
+ $(parentId).append(child);
65
+ // Ensure the cloned input fields are unique.
66
+ $('#' + child.attr("id") + " :input").each(function(){
67
+ incrementInputId(this);
68
+ incrementInputName(this);
69
+ $(this).attr("value", '');
70
+ return this;
71
+ });
72
+ // Ensure the cloned destroy link is unique.
73
+ destroyLink = $("a.destroy-nested:last");
74
+ destroyLink.attr("id", incrementText(destroyLink.attr("id")));
75
+ // Ensure that the default event does not fire.
76
+ return false;
77
+ });
78
+
79
+ // Nested Destroy
80
+ $("a.destroy-nested").click(function(){
81
+ try {
82
+ var id = $(this).attr("id");
83
+ var parentId = stringChop(id);
84
+ if (parentId != id) {
85
+ parentId = '#' + parentId;
86
+ $(parentId).prepend(generateDestroyInput($(parentId + " input:first").clone()));
87
+ animateDestroy(parentId);
88
+ } else {
89
+ throw "Invalid ID";
90
+ }
91
+ } catch (e) {
92
+ alert("Error: " + e + ". Check that parent ID is defined and/or the link ID includes parent ID as part of the link ID.");
93
+ }
94
+ // Ensure that the default event does not fire.
95
+ return false;
96
+ });
97
+
98
+ // Destroy
99
+ $("a.destroy").click(function(){
100
+ var result = confirm("Are you sure you want to delete this?");
101
+ if (result) {
102
+ try {
103
+ var id = $(this).attr("id");
104
+ var parentId = stringChop(id);
105
+ if (parentId != id) {
106
+ animateDestroy('#' + parentId);
107
+ } else {
108
+ throw "Invalid ID";
109
+ }
110
+ // Finally, call the destroy action.
111
+ $.post($(this).attr("href"), "_method=delete");
112
+ } catch (e) {
113
+ alert("Error: " + e + ". Check that parent ID is defined and/or the link ID includes parent ID as part of the link ID.");
114
+ }
115
+ }
116
+ // Ensure that the default event does not fire.
117
+ return false;
118
+ });
119
+ });
@@ -1,4 +1,4 @@
1
- class RestSetupGenerator < Rails::Generator::Base
1
+ class UjsSetupGenerator < Rails::Generator::Base
2
2
  def manifest
3
3
  record do |m|
4
4
  # Controllers
@@ -8,7 +8,7 @@ class RestSetupGenerator < Rails::Generator::Base
8
8
  m.directory "app/views/javascripts"
9
9
  m.file "app/views/javascripts/ujs.js.erb", "app/views/javascripts/ujs.js.erb"
10
10
 
11
- # JavaScripts
11
+ # JavaScript
12
12
  m.file "public/javascripts/rest.js", "public/javascripts/rest.js"
13
13
 
14
14
  # Instructions
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aeonscope-btech_rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-15 00:00:00 -07:00
12
+ date: 2009-04-18 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -51,12 +51,12 @@ files:
51
51
  - lib/btech_rest.rb
52
52
  - lib/class_methods.rb
53
53
  - lib/resource_helper.rb
54
- - rails_generators/rest_setup/USAGE
55
- - rails_generators/rest_setup/rest_setup_generator.rb
56
- - rails_generators/rest_setup/templates/README
57
- - rails_generators/rest_setup/templates/app/controllers/javascripts_controller.rb
58
- - rails_generators/rest_setup/templates/app/views/javascripts/ujs.js.erb
59
- - rails_generators/rest_setup/templates/public/javascripts/rest.js
54
+ - rails_generators/ujs_setup/USAGE
55
+ - rails_generators/ujs_setup/templates/README
56
+ - rails_generators/ujs_setup/templates/app/controllers/javascripts_controller.rb
57
+ - rails_generators/ujs_setup/templates/app/views/javascripts/ujs.js.erb
58
+ - rails_generators/ujs_setup/templates/public/javascripts/rest.js
59
+ - rails_generators/ujs_setup/ujs_setup_generator.rb
60
60
  - test/btech_rest_test.rb
61
61
  - test/test_helper.rb
62
62
  has_rdoc: true
@@ -84,7 +84,7 @@ requirements: []
84
84
  rubyforge_project:
85
85
  rubygems_version: 1.2.0
86
86
  signing_key:
87
- specification_version: 2
87
+ specification_version: 3
88
88
  summary: Enables default REST functionality, more than what you get with Rails out-of-the-box, and keeps your code DRY.
89
89
  test_files:
90
90
  - test/btech_rest_test.rb
@@ -1,11 +0,0 @@
1
- Berserk Technologies REST Setup Generator
2
-
3
- Description:
4
- Configures unobtrusive jQuery support.
5
-
6
- Requirements
7
- 1. jQuery 1.3 or higher.
8
- 2. jQuery UI 1.7 or higher.
9
-
10
- Usage:
11
- script/generate rest_setup
@@ -1,7 +0,0 @@
1
- # Enables the ability to serve up dynamic javascript, namely Unobtrusive JavaScript
2
- # support for jQuery.
3
- class JavascriptsController < ApplicationController
4
- # Serves global jQuery UJS settings. See the /views/layouts/application.html.erb for usage.
5
- def ujs
6
- end
7
- end
@@ -1,133 +0,0 @@
1
- // Chops off the last string segment per delimiter. If no delimiter is found in the string then the original string is
2
- // returned instead. The following attributes are accepted:
3
- // string = Required. The string to chop.
4
- // delimiter = Optional. The delimiter used to chop up the string. Defaults to '_'.
5
- function chop_last(string, delimiter) {
6
- var chopped = string;
7
- if (delimiter == undefined) {delimiter = '_';}
8
- var endIndex = string.lastIndexOf(delimiter);
9
- if (endIndex > 1) {chopped = string.slice(0, endIndex);}
10
- return chopped;
11
- }
12
-
13
- // Increments a number embedded in the text by one. If no number is found then the original text is returned.
14
- function increment_text(text) {
15
- var match = text.match(/\d+/);
16
- if (match != null) {
17
- var number = new Number(match);
18
- var new_number = number + 1;
19
- text = text.replace(number, new_number);
20
- }
21
- return text;
22
- };
23
-
24
- // Suffixes text with a number. Accepts the following arguments:
25
- // text = Required. The text to suffix.
26
- // number = Optional. The number to be suffixed to the text. Defaults to 1.
27
- // delimiter = Optional. The delimiter between the text and number. Defaults to '_'.
28
- function suffix_num_to_text(text, number, delimiter) {
29
- if (text != null) {
30
- if (number == undefined) { number = 1; };
31
- if (delimiter == undefined) { delimiter = '_'; };
32
- return text + delimiter + number;
33
- };
34
- };
35
-
36
- // Increments the input field ID number by one so ActiveRecord can save new record attributes.
37
- function increment_input_id(input) {
38
- id = $(input).attr("id");
39
- id = increment_text(id);
40
- $(input).attr("id", id);
41
- };
42
-
43
- // Increments the input field name number by one so ActiveRecord can save new record attributes.
44
- function increment_input_name(input) {
45
- name = $(input).attr("name");
46
- name = increment_text(name);
47
- $(input).attr("name", name);
48
- };
49
-
50
- // Generates a hidden input field based off original input field data that instructs ActiveRecord to delete
51
- // a record based on the ID of the input field.
52
- function generate_destroy_input(input) {
53
- $(input).attr("id", chop_last($(input).attr("id")) + "__delete");
54
- $(input).attr("name", chop_last($(input).attr("name"), '[') + "[_delete]");
55
- $(input).attr("type", "hidden");
56
- $(input).attr("value", 1);
57
- return input;
58
- }
59
-
60
- // UJS
61
- $(document).ready(function(){
62
- // Nested New
63
- $("a.nested-new").click(function(){
64
- var id = $(this).attr("id");
65
- var parent_id = '#' + chop_last(id);
66
- var clone = $(parent_id + " tr:last").clone(true);
67
- var clone_id = clone.attr("id");
68
- // Clone for new action.
69
- if (clone_id.length > 4 && clone_id.substr(0, 4) == "new_") {
70
- clone_id = clone_id.slice(4);
71
- clone_id = suffix_num_to_text(clone_id);
72
- clone.attr("id", clone_id);
73
- }
74
- // Clone for edit action.
75
- else {
76
- clone.attr("id", increment_text(clone_id));
77
- }
78
- $(parent_id).append(clone);
79
- // Ensure all cloned input fields are unique.
80
- $.each($('#' + clone.attr("id") + " :input"), function(){
81
- increment_input_id(this);
82
- increment_input_name(this);
83
- $(this).attr("value", '');
84
- return this;
85
- });
86
- // Ensure default event does not fire.
87
- return false;
88
- });
89
-
90
- // Nested Destroy
91
- $("a.nested-destroy").click(function(){
92
- try {
93
- var id = $(this).attr("id");
94
- var parent_id = chop_last(id);
95
- if (parent_id != id) {
96
- parent_id = '#' + parent_id;
97
- $(parent_id).prepend(generate_destroy_input($(parent_id + " input:first").clone()));
98
- $(parent_id).animate({backgroundColor: "#FF0000"}, 500);
99
- $(parent_id).fadeOut(500);
100
- } else {
101
- throw "Invalid ID";
102
- }
103
- } catch (e) {
104
- alert("Error: " + e + ". Check that parent ID is defined and/or the link ID includes parent ID as part of the link ID.");
105
- }
106
- // Ensure default event does not fire.
107
- return false;
108
- });
109
-
110
- // Destroy
111
- $("a.destroy").click(function(){
112
- var result = confirm("Are you sure you want to delete this?");
113
- if (result) {
114
- try {
115
- var id = $(this).attr("id");
116
- var parent_id = chop_last(id);
117
- if (parent_id != id) {
118
- parent_id = '#' + parent_id;
119
- $(parent_id).animate({backgroundColor: "#FF0000"}, 500);
120
- $(parent_id).fadeOut(500);
121
- } else {
122
- throw "Invalid ID";
123
- }
124
- // Finally, call the destroy action.
125
- $.post($(this).attr("href"), "_method=delete");
126
- } catch (e) {
127
- alert("Error: " + e + ". Check that parent ID is defined and/or the link ID includes parent ID as part of the link ID.");
128
- }
129
- }
130
- // Ensure default event does not fire.
131
- return false;
132
- });
133
- });