dry_crud 0.6.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 (53) hide show
  1. data/MIT-LICENSE +19 -0
  2. data/README.rdoc +208 -0
  3. data/Rakefile +101 -0
  4. data/VERSION +1 -0
  5. data/rails_generators/dry_crud/USAGE +1 -0
  6. data/rails_generators/dry_crud/dry_crud_generator.rb +22 -0
  7. data/rails_generators/dry_crud/templates/INSTALL +13 -0
  8. data/rails_generators/dry_crud/templates/app/controllers/crud_controller.rb +182 -0
  9. data/rails_generators/dry_crud/templates/app/helpers/crud_helper.rb +45 -0
  10. data/rails_generators/dry_crud/templates/app/helpers/standard_helper.rb +209 -0
  11. data/rails_generators/dry_crud/templates/app/views/crud/_attrs.html.erb +1 -0
  12. data/rails_generators/dry_crud/templates/app/views/crud/_form.html.erb +1 -0
  13. data/rails_generators/dry_crud/templates/app/views/crud/_list.html.erb +1 -0
  14. data/rails_generators/dry_crud/templates/app/views/crud/edit.html.erb +8 -0
  15. data/rails_generators/dry_crud/templates/app/views/crud/index.html.erb +14 -0
  16. data/rails_generators/dry_crud/templates/app/views/crud/new.html.erb +7 -0
  17. data/rails_generators/dry_crud/templates/app/views/crud/show.html.erb +9 -0
  18. data/rails_generators/dry_crud/templates/app/views/layouts/crud.html.erb +20 -0
  19. data/rails_generators/dry_crud/templates/app/views/shared/_labeled.html.erb +5 -0
  20. data/rails_generators/dry_crud/templates/lib/crud_callbacks.rb +55 -0
  21. data/rails_generators/dry_crud/templates/lib/render_inheritable.rb +118 -0
  22. data/rails_generators/dry_crud/templates/lib/standard_form_builder.rb +161 -0
  23. data/rails_generators/dry_crud/templates/lib/standard_table_builder.rb +104 -0
  24. data/rails_generators/dry_crud/templates/public/stylesheets/crud.css +91 -0
  25. data/rails_generators/dry_crud/templates/test/crud_test_model.rb +124 -0
  26. data/rails_generators/dry_crud/templates/test/functional/crud_controller_test_helper.rb +172 -0
  27. data/rails_generators/dry_crud/templates/test/functional/crud_test_models_controller_test.rb +96 -0
  28. data/rails_generators/dry_crud/templates/test/unit/crud_helper_test.rb +57 -0
  29. data/rails_generators/dry_crud/templates/test/unit/render_inheritable_test.rb +161 -0
  30. data/rails_generators/dry_crud/templates/test/unit/standard_form_builder_test.rb +83 -0
  31. data/rails_generators/dry_crud/templates/test/unit/standard_helper_test.rb +183 -0
  32. data/rails_generators/dry_crud/templates/test/unit/standard_table_builder_test.rb +99 -0
  33. data/test/templates/app/controllers/ajax_controller.rb +7 -0
  34. data/test/templates/app/controllers/application_controller.rb +11 -0
  35. data/test/templates/app/controllers/cities_controller.rb +13 -0
  36. data/test/templates/app/controllers/people_controller.rb +7 -0
  37. data/test/templates/app/helpers/people_helper.rb +7 -0
  38. data/test/templates/app/models/city.rb +13 -0
  39. data/test/templates/app/models/person.rb +9 -0
  40. data/test/templates/app/views/ajax/_hello.html.erb +1 -0
  41. data/test/templates/app/views/ajax/ajax.js.rjs +1 -0
  42. data/test/templates/app/views/ajax/index.html.erb +9 -0
  43. data/test/templates/app/views/cities/_attrs.html.erb +1 -0
  44. data/test/templates/app/views/cities/_form.html.erb +4 -0
  45. data/test/templates/app/views/cities/_hello.html.erb +1 -0
  46. data/test/templates/app/views/cities/_list.html.erb +5 -0
  47. data/test/templates/config/routes.rb +11 -0
  48. data/test/templates/db/migrate/20100511174904_create_people_and_cities.rb +23 -0
  49. data/test/templates/test/fixtures/cities.yml +11 -0
  50. data/test/templates/test/fixtures/people.yml +14 -0
  51. data/test/templates/test/functional/cities_controller_test.rb +35 -0
  52. data/test/templates/test/functional/people_controller_test.rb +30 -0
  53. metadata +127 -0
@@ -0,0 +1,161 @@
1
+ require 'test_helper'
2
+
3
+ TEST_VIEW_PATH = File.join(RAILS_ROOT, 'test', 'test_views')
4
+
5
+ class RootController < ActionController::Base
6
+ include RenderInheritable
7
+
8
+ attr_accessor :default_template_format
9
+
10
+ append_view_path(TEST_VIEW_PATH)
11
+
12
+ def initialize(*args)
13
+ super(*args)
14
+ self.default_template_format = :html
15
+ end
16
+
17
+ def view_paths
18
+ self.class.view_paths
19
+ end
20
+
21
+ end
22
+
23
+ class ChildrenController < RootController
24
+
25
+ end
26
+
27
+ class GrandChildrenController < ChildrenController
28
+
29
+ end
30
+
31
+ # mock File ojbect
32
+ class File
33
+ class << self
34
+ def touched
35
+ @touched ||= []
36
+ end
37
+
38
+ alias_method :orig_exists?, :exists?
39
+ def exists?(filename, *args)
40
+ touched.include?(filename) || orig_exists?(filename, *args)
41
+ end
42
+
43
+ def touch_template(file)
44
+ touched << File.join(ActionController::Base.view_paths.first, "#{file}.html.erb")
45
+ end
46
+ end
47
+ end
48
+
49
+ class RenderInheritableTest < ActiveSupport::TestCase
50
+
51
+ attr_reader :controller, :grand_controller
52
+
53
+ def setup
54
+ teardown
55
+ @controller = ChildrenController.new
56
+ @grand_controller = GrandChildrenController.new
57
+ ChildrenController.inheritable_cache.clear
58
+ GrandChildrenController.inheritable_cache.clear
59
+ end
60
+
61
+ def teardown
62
+ FileUtils.rm_rf(TEST_VIEW_PATH)
63
+ end
64
+
65
+ test "inheritable_root_controller" do
66
+ assert_equal RootController, RootController.inheritable_root_controller
67
+ assert_equal RootController, ChildrenController.inheritable_root_controller
68
+ assert_equal RootController, GrandChildrenController.inheritable_root_controller
69
+ end
70
+
71
+ test "lookup path" do
72
+ assert_equal ['children', 'root'], ChildrenController.send(:lookup_path)
73
+ assert_equal ['grand_children', 'children', 'root'], GrandChildrenController.send(:lookup_path)
74
+ end
75
+
76
+ test "inheritable controller without routes finds root" do
77
+ assert_equal 'root', ChildrenController.send(:inheritable_controller)
78
+ assert_equal 'root', GrandChildrenController.send(:inheritable_controller)
79
+ end
80
+
81
+ test "find non-existing inheritable file" do
82
+ assert_nil ChildrenController.send(:find_inheritable_file, 'foo')
83
+ end
84
+
85
+ test "find inheritable file not overwritten" do
86
+ touch("root/root.html.erb")
87
+
88
+ assert_equal 'root', ChildrenController.send(:find_inheritable_file, 'root')
89
+ assert_equal 'root', GrandChildrenController.send(:find_inheritable_file, 'root')
90
+ end
91
+
92
+ test "find inheritable file partially overwritten" do
93
+ touch("root/child.html.erb")
94
+ touch("children/child.html.erb")
95
+
96
+ assert_equal 'children', ChildrenController.send(:find_inheritable_file, 'child')
97
+ assert_equal 'children', GrandChildrenController.send(:find_inheritable_file, 'child')
98
+ end
99
+
100
+ test "find inheritable file partially overwritten with gaps" do
101
+ touch("root/grandchild.html.erb")
102
+ touch("grand_children/grandchild.rhtml")
103
+
104
+ assert_equal 'root', ChildrenController.send(:find_inheritable_file, 'grandchild')
105
+ assert_equal 'grand_children', GrandChildrenController.send(:find_inheritable_file, 'grandchild')
106
+ end
107
+
108
+ test "find inheritable file for js format" do
109
+ touch("root/_grandchild.js.rjs")
110
+ touch("grand_children/_grandchild.js.rjs")
111
+
112
+ assert_equal 'root', ChildrenController.send(:find_inheritable_file, '_grandchild', :js)
113
+ assert_equal 'grand_children', GrandChildrenController.send(:find_inheritable_file, '_grandchild', :js)
114
+
115
+ assert_equal({:js => { '_grandchild' => {nil => 'root'}}}, ChildrenController.inheritable_cache)
116
+ assert_equal({:js => { '_grandchild' => {nil => 'grand_children'}}}, GrandChildrenController.inheritable_cache)
117
+ end
118
+
119
+ test "find inheritable file for xml format" do
120
+ touch("root/_grandchild.xml.builder")
121
+ touch("grand_children/_grandchild.xml.builder")
122
+
123
+ assert_equal 'root', ChildrenController.send(:find_inheritable_file, '_grandchild', :xml)
124
+ assert_equal 'grand_children', GrandChildrenController.send(:find_inheritable_file, '_grandchild', :xml)
125
+ end
126
+
127
+ test "find inheritable file all overwritten" do
128
+ touch("root/all.html.erb")
129
+ touch("children/all.rhtml")
130
+ touch("grand_children/all.html.erb")
131
+
132
+ assert_equal 'children', ChildrenController.send(:find_inheritable_file, 'all')
133
+ assert_equal 'grand_children', GrandChildrenController.send(:find_inheritable_file, 'all')
134
+
135
+ assert_equal({:html => { 'all' => {nil => 'children'}}}, ChildrenController.inheritable_cache)
136
+ assert_equal({:html => { 'all' => {nil => 'grand_children'}}}, GrandChildrenController.inheritable_cache)
137
+
138
+ assert_equal 'children', ChildrenController.send(:find_inheritable_file, 'all')
139
+ assert_equal 'grand_children', GrandChildrenController.send(:find_inheritable_file, 'all')
140
+
141
+ assert_equal({:html => { 'all' => {nil => 'children'}}}, ChildrenController.inheritable_cache)
142
+ assert_equal({:html => { 'all' => {nil => 'grand_children'}}}, GrandChildrenController.inheritable_cache)
143
+ end
144
+
145
+
146
+
147
+ private
148
+
149
+ def touch(file)
150
+ #File.touch_template(file)
151
+ f = File.join(TEST_VIEW_PATH, file)
152
+ FileUtils.mkdir_p(File.dirname(f))
153
+ FileUtils.touch(f)
154
+
155
+ RootController.view_paths.last.instance_variable_set(:@loaded, false)
156
+ RootController.view_paths.last.load!
157
+ end
158
+
159
+
160
+
161
+ end
@@ -0,0 +1,83 @@
1
+ require 'test_helper'
2
+ require 'crud_test_model'
3
+
4
+ class StandardFormBuilderTest < ActionView::TestCase
5
+
6
+ include CrudTestHelper
7
+
8
+ # set dummy helper class for ActionView::TestCase
9
+ self.helper_class = StandardHelper
10
+
11
+ attr_reader :form, :entry
12
+
13
+ setup :reset_db, :setup_db, :create_test_data, :create_form
14
+ teardown :reset_db
15
+
16
+ def create_form
17
+ @entry = CrudTestModel.first
18
+ @form = StandardFormBuilder.new(:entry, @entry, self, {}, lambda {|form| form })
19
+ end
20
+
21
+ test "input_field dispatches string attr to string_field" do
22
+ assert_equal form.string_field(:name), form.input_field(:name)
23
+ end
24
+
25
+ test "input_field dispatches text attr to text_area" do
26
+ assert_equal form.text_area(:remarks), form.input_field(:remarks)
27
+ end
28
+
29
+ test "input_field dispatches integer attr to integer_field" do
30
+ assert_equal form.integer_field(:children), form.input_field(:children)
31
+ end
32
+
33
+ test "input_field dispatches boolean attr to boolean_field" do
34
+ assert_equal form.boolean_field(:human), form.input_field(:human)
35
+ end
36
+
37
+ test "input_field dispatches date attr to date_field" do
38
+ assert_equal form.date_field(:birthdate), form.input_field(:birthdate)
39
+ end
40
+
41
+ test "input_field dispatches belongs_to attr to select field" do
42
+ assert_equal form.belongs_to_field(:companion_id), form.input_field(:companion_id)
43
+ end
44
+
45
+ test "belongs_to_field has all options by default" do
46
+ f = form.belongs_to_field(:companion_id)
47
+ assert_match /(\<option .*?){7}/m, f
48
+ assert_no_match /(\<option .*?){8}/m, f
49
+ end
50
+
51
+ test "belongs_to_field with :list option" do
52
+ list = CrudTestModel.all
53
+ f = form.belongs_to_field(:companion_id, :list => [list.first, list.second])
54
+ assert_match /(\<option .*?){3}/m, f
55
+ assert_no_match /(\<option .*?){4}/m, f
56
+ end
57
+
58
+ test "belongs_to_field with instance variable" do
59
+ list = CrudTestModel.all
60
+ @companions = [list.first, list.second]
61
+ f = form.belongs_to_field(:companion_id)
62
+ assert_match /(\<option .*?){3}/m, f
63
+ assert_no_match /(\<option .*?){4}/m, f
64
+ end
65
+
66
+ test "belongs_to_field with empty list" do
67
+ @companions = []
68
+ f = form.belongs_to_field(:companion_id)
69
+ assert_match /none available/m, f
70
+ assert_no_match /(\<option .*?)/m, f
71
+ end
72
+
73
+
74
+ test "string_field sets maxlength attribute if limit" do
75
+ assert_match /maxlength="50"/, form.string_field(:name)
76
+ end
77
+
78
+ test "labeld_text_field create label" do
79
+ assert_match /label for.+input/m, form.labeled_string_field(:name)
80
+ end
81
+
82
+
83
+ end
@@ -0,0 +1,183 @@
1
+ require 'test_helper'
2
+ require 'crud_test_model'
3
+
4
+ class StandardHelperTest < ActionView::TestCase
5
+
6
+ include StandardHelper
7
+ include CrudTestHelper
8
+
9
+ setup :reset_db, :setup_db, :create_test_data
10
+ teardown :reset_db
11
+
12
+ def format_size(obj)
13
+ "#{f(obj.size)} chars"
14
+ end
15
+
16
+ test "labeled text as block" do
17
+ result = labeled("label") { "value" }
18
+
19
+ assert_dom_equal "<div class='labeled'><div class='caption'>label</div><div class='value'>value</div></div>", result
20
+ end
21
+
22
+ test "labeled text empty" do
23
+ result = labeled("label", "")
24
+
25
+ assert_dom_equal "<div class='labeled'><div class='caption'>label</div><div class='value'>#{EMPTY_STRING}</div></div>", result
26
+ end
27
+
28
+ test "labeled text as content" do
29
+ result = labeled("label", "value")
30
+
31
+ assert_dom_equal "<div class='labeled'><div class='caption'>label</div><div class='value'>value</div></div>", result
32
+ end
33
+
34
+ test "alternate row" do
35
+ result_1 = tr_alt { "(test row content)" }
36
+ result_2 = tr_alt { "(test row content)" }
37
+
38
+ assert_dom_equal "<tr class='even'>(test row content)</tr>", result_1
39
+ assert_dom_equal "<tr class='odd'>(test row content)</tr>", result_2
40
+ end
41
+
42
+ test "format Fixnums" do
43
+ assert_equal "0", f(0)
44
+ assert_equal "10", f(10)
45
+ assert_equal "10,000,000", f(10000000)
46
+ end
47
+
48
+ test "format Floats" do
49
+ assert_equal "1.00", f(1.0)
50
+ assert_equal "1.20", f(1.2)
51
+ assert_equal "3.14", f(3.14159)
52
+ end
53
+
54
+ test "format Booleans" do
55
+ assert_equal "yes", f(true)
56
+ assert_equal "no", f(false)
57
+ end
58
+
59
+ test "format nil" do
60
+ assert_equal EMPTY_STRING, f(nil)
61
+ end
62
+
63
+ test "format Strings" do
64
+ assert_equal "blah blah", f("blah blah")
65
+ assert_equal "&lt;injection&gt;", f("<injection>")
66
+ end
67
+
68
+ test "format attr with fallthrough to f" do
69
+ assert_equal "12.23", format_attr("12.23424", :to_f)
70
+ end
71
+
72
+ test "format attr with custom format_size method" do
73
+ assert_equal "4 chars", format_attr("abcd", :size)
74
+ end
75
+
76
+ test "column types" do
77
+ m = crud_test_models(:AAAAA)
78
+ assert_equal :string, column_type(m, :name)
79
+ assert_equal :integer, column_type(m, :children)
80
+ assert_equal :integer, column_type(m, :companion_id)
81
+ assert_equal nil, column_type(m, :companion)
82
+ assert_equal :float, column_type(m, :rating)
83
+ assert_equal :decimal, column_type(m, :income)
84
+ assert_equal :date, column_type(m, :birthdate)
85
+ assert_equal :boolean, column_type(m, :human)
86
+ assert_equal :text, column_type(m, :remarks)
87
+ end
88
+
89
+ test "format integer column" do
90
+ m = crud_test_models(:AAAAA)
91
+ assert_equal '1', format_type(m, :children)
92
+
93
+ m.children = 10000
94
+ assert_equal '10,000', format_type(m, :children)
95
+ end
96
+
97
+ test "format float column" do
98
+ m = crud_test_models(:AAAAA)
99
+ assert_equal '1.10', format_type(m, :rating)
100
+
101
+ m.rating = 3.145
102
+ assert_equal '3.15', format_type(m, :rating)
103
+ end
104
+
105
+ test "format decimal column" do
106
+ m = crud_test_models(:AAAAA)
107
+ assert_equal '10000000.10', format_type(m, :income)
108
+ end
109
+
110
+ test "format date column" do
111
+ m = crud_test_models(:AAAAA)
112
+ assert_equal '1910-01-01', format_type(m, :birthdate)
113
+ end
114
+
115
+ test "format text column" do
116
+ m = crud_test_models(:AAAAA)
117
+ assert_equal "<p>AAAAA AAAAA AAAAA\n<br />AAAAA AAAAA AAAAA\n<br />AAAAA AAAAA AAAAA\n</p>", format_type(m, :remarks)
118
+ end
119
+
120
+ test "empty table should render message" do
121
+ assert_dom_equal "<div class='list'>#{NO_LIST_ENTRIES_MESSAGE}</div>", table([]) { }
122
+ end
123
+
124
+ test "non empty table should render table" do
125
+ assert_match(/^\<table.*\<\/table\>$/, table(['foo', 'bar']) {|t| t.attrs :size, :upcase })
126
+ end
127
+
128
+ test "captionize" do
129
+ assert_equal "Camel Case", captionize(:camel_case)
130
+ assert_equal "All Upper Case", captionize("all upper case")
131
+ assert_equal "With Object", captionize("With object", Object.new)
132
+ end
133
+
134
+ test "standard form for existing entry" do
135
+ e = crud_test_models('AAAAA')
136
+ f = capture { standard_form(e, [:name, :children, :birthdate, :human], :class => 'special') }
137
+
138
+ assert_match /form .*?action="\/crud_test_models\/#{e.id}" .*?method="post"/, f
139
+ assert_match /input .*?name="_method" .*?type="hidden" .*?value="put"/, f
140
+ assert_match /input .*?name="crud_test_model\[name\]" .*?type="text" .*?value="AAAAA"/, f
141
+ assert_match /select .*?name="crud_test_model\[birthdate\(1i\)\]"/, f
142
+ assert_match /option selected="selected" value="1910">1910<\/option>/, f
143
+ assert_match /option selected="selected" value="1">January<\/option>/, f
144
+ assert_match /option selected="selected" value="1">1<\/option>/, f
145
+ assert_match /input .*?name="crud_test_model\[children\]" .*?type="text" .*?value=\"1\"/, f
146
+ assert_match /input .*?name="crud_test_model\[human\]" .*?type="checkbox"/, f
147
+ assert_match /input .*?type="submit" .*?value="Save"/, f
148
+ end
149
+
150
+ test "standard form for new entry" do
151
+ e = CrudTestModel.new
152
+ f = capture { standard_form(e, [:name, :children, :birthdate, :human], :class => 'special') }
153
+
154
+ assert_match /form .*?action="\/crud_test_models" .*?method="post"/, f
155
+ assert_match /input .*?name="crud_test_model\[name\]" .*?type="text"/, f
156
+ assert_no_match /input .*?name="crud_test_model\[name\]" .*?type="text" .*?value=/, f
157
+ assert_match /select .*?name="crud_test_model\[birthdate\(1i\)\]"/, f
158
+ assert_match /input .*?name="crud_test_model\[children\]" .*?type="text"/, f
159
+ assert_no_match /input .*?name="crud_test_model\[children\]" .*?type="text" .*?value=/, f
160
+ assert_match /input .*?type="submit" .*?value="Save"/, f
161
+ end
162
+
163
+ test "standard form with errors" do
164
+ e = crud_test_models('AAAAA')
165
+ e.name = nil
166
+ assert !e.valid?
167
+
168
+ f = capture { standard_form(e, [:name, :children, :birthdate, :human], :class => 'special') }
169
+
170
+ assert_match /form .*?action="\/crud_test_models\/#{e.id}" .*?method="post"/, f
171
+ assert_match /input .*?name="_method" .*?type="hidden" .*?value="put"/, f
172
+ assert_match /div class="errorExplanation"/, f
173
+ assert_match /div class="fieldWithErrors"\>.*?\<input .*?name="crud_test_model\[name\]" .*?type="text"/, f
174
+ assert_match /select .*?name="crud_test_model\[birthdate\(1i\)\]"/, f
175
+ assert_match /option selected="selected" value="1910">1910<\/option>/, f
176
+ assert_match /option selected="selected" value="1">January<\/option>/, f
177
+ assert_match /option selected="selected" value="1">1<\/option>/, f
178
+ assert_match /input .*?name="crud_test_model\[children\]" .*?type="text" .*?value=\"1\"/, f
179
+ assert_match /input .*?name="crud_test_model\[human\]" .*?type="checkbox"/, f
180
+ assert_match /input .*?type="submit" .*?value="Save"/, f
181
+ end
182
+
183
+ end
@@ -0,0 +1,99 @@
1
+ require 'test_helper'
2
+
3
+ class StandardTableBuilderTest < ActionView::TestCase
4
+
5
+ # set dummy helper class for ActionView::TestCase
6
+ self.helper_class = StandardHelper
7
+
8
+ attr_reader :table
9
+
10
+ def setup
11
+ @table = StandardTableBuilder.new(["foo", "bahr"], self)
12
+ end
13
+
14
+ def format_size(obj)
15
+ "#{obj.size} chars"
16
+ end
17
+
18
+ test "html header" do
19
+ table.attrs :upcase, :size
20
+
21
+ dom = '<tr><th>Upcase</th><th>Size</th></tr>'
22
+
23
+ assert_dom_equal dom, table.send(:html_header)
24
+ end
25
+
26
+ test "single attr row" do
27
+ table.attrs :upcase, :size
28
+
29
+ dom = '<tr class="even"><td>FOO</td><td>3 chars</td></tr>'
30
+
31
+ assert_dom_equal dom, table.send(:html_row, "foo")
32
+ end
33
+
34
+ test "custom row" do
35
+ table.col("Header", :class => 'hula') {|e| "Weights #{e.size} kg" }
36
+
37
+ dom = '<tr class="even"><td class="hula">Weights 3 kg</td></tr>'
38
+
39
+ assert_dom_equal dom, table.send(:html_row, "foo")
40
+ end
41
+
42
+ test "attr col output" do
43
+ table.attrs :upcase
44
+ col = table.cols.first
45
+
46
+ assert_equal "<th>Upcase</th>", col.html_header
47
+ assert_equal "FOO", col.content("foo")
48
+ assert_equal "<td>FOO</td>", col.html_cell("foo")
49
+ end
50
+
51
+ test "attr col content with custom format_size method" do
52
+ table.attrs :size
53
+ col = table.cols.first
54
+
55
+ assert_equal "4 chars", col.content("abcd")
56
+ end
57
+
58
+ test "two x two table" do
59
+ dom = <<-FIN
60
+ <table class="list">
61
+ <tr><th>Upcase</th><th>Size</th></tr>
62
+ <tr class="even"><td>FOO</td><td>3 chars</td></tr>
63
+ <tr class="odd"><td>BAHR</td><td>4 chars</td></tr>
64
+ </table>
65
+ FIN
66
+
67
+ table.attrs :upcase, :size
68
+
69
+ assert_dom_equal dom, table.to_html
70
+ end
71
+
72
+ test "table with before and after cells" do
73
+ dom = <<-FIN
74
+ <table class="list">
75
+ <tr><th>head</th><th>Upcase</th><th>Size</th><th></th></tr>
76
+ <tr class="even">
77
+ <td class='left'><a href='/'>foo</a></td>
78
+ <td>FOO</td>
79
+ <td>3 chars</td>
80
+ <td>Never foo</td>
81
+ </tr>
82
+ <tr class="odd">
83
+ <td class='left'><a href='/'>bahr</a></td>
84
+ <td>BAHR</td>
85
+ <td>4 chars</td>
86
+ <td>Never bahr</td>
87
+ </tr>
88
+ </table>
89
+ FIN
90
+
91
+ table.col('head', :class => 'left') { |e| link_to e, "/" }
92
+ table.attrs :upcase, :size
93
+ table.col { |e| "Never #{e}" }
94
+
95
+ assert_dom_equal dom, table.to_html
96
+ end
97
+
98
+
99
+ end
@@ -0,0 +1,7 @@
1
+ class AjaxController < CrudController
2
+
3
+ def ajax
4
+
5
+ end
6
+
7
+ end
@@ -0,0 +1,11 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ helper :standard
6
+
7
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
8
+
9
+ # Scrub sensitive parameters from your log
10
+ # filter_parameter_logging :password
11
+ end
@@ -0,0 +1,13 @@
1
+ class CitiesController < AjaxController
2
+
3
+ def show
4
+ respond_to do |format|
5
+ format.html do
6
+ flash[:notice] = flash[:notice]
7
+ redirect_to :action => 'index'
8
+ end
9
+ format.xml { render :xml => @entry }
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,7 @@
1
+ class PeopleController < AjaxController
2
+
3
+ def fetch_all_options
4
+ {:include => :city, :order => 'people.name, cities.country_code, cities.name'}
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ module PeopleHelper
2
+
3
+ def format_income(person)
4
+ "#{f(person.income)} $"
5
+ end
6
+
7
+ end
@@ -0,0 +1,13 @@
1
+ class City < ActiveRecord::Base
2
+
3
+ has_many :people
4
+
5
+ validates_presence_of :name, :country_code
6
+
7
+ default_scope :order => 'country_code, name'
8
+
9
+ def label
10
+ "#{name} (#{country_code})"
11
+ end
12
+
13
+ end
@@ -0,0 +1,9 @@
1
+ class Person < ActiveRecord::Base
2
+
3
+ alias_attribute :label, :name
4
+
5
+ belongs_to :city
6
+
7
+ validates_presence_of :name
8
+
9
+ end
@@ -0,0 +1 @@
1
+ hello from ajax
@@ -0,0 +1 @@
1
+ page.replace_html(:response, render_inheritable(:partial => 'hello'))
@@ -0,0 +1,9 @@
1
+ <% @title = "Listing #{models_label}" -%>
2
+
3
+ <%= render_inheritable :partial => 'list' %>
4
+
5
+ <br/>
6
+
7
+ <%= link_action_add %>
8
+ <%= link_to_remote 'Ajahx', :url => {:action => 'ajax'}, :method => :get %>
9
+ <div id="response"></div>
@@ -0,0 +1 @@
1
+ <%= render_attrs @entry, default_attrs %>
@@ -0,0 +1,4 @@
1
+ <% crud_form do |f| -%>
2
+ <%= f.labeled_input_field :name %>
3
+ <%= f.labeled_collection_select(:country_code, ['BR', 'CH', 'DE', 'GB', 'JP', 'USA'], :to_s, :to_s, { :include_blank => "Please select" })%>
4
+ <% end -%>
@@ -0,0 +1 @@
1
+ hello from cities
@@ -0,0 +1,5 @@
1
+ <%= crud_table do |t|
2
+ t.attrs :name, :country_code
3
+ t.col {|e| link_action_edit(e) }
4
+ t.col {|e| link_action_destroy(e) }
5
+ end %>
@@ -0,0 +1,11 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+
3
+ map.resources :cities, :new => {:ajax => :get}
4
+ map.resources :people, :new => {:ajax => :get}
5
+
6
+ # Install the default routes as the lowest priority.
7
+ # Note: These default routes make all actions in every controller accessible via GET requests. You should
8
+ # consider removing or commenting them out if you're using named routes and resources.
9
+ map.connect ':controller/:action/:id'
10
+ map.connect ':controller/:action/:id.:format'
11
+ end
@@ -0,0 +1,23 @@
1
+ class CreatePeopleAndCities < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :cities do |t|
4
+ t.string :name, :null => false
5
+ t.string :country_code, :null => false, :limit => 3
6
+ end
7
+
8
+ create_table :people do |t|
9
+ t.string :name, :null => false
10
+ t.integer :children
11
+ t.integer :city_id
12
+ t.float :rating
13
+ t.decimal :income, :precision => 14, :scale => 2
14
+ t.date :birthdate
15
+ t.text :remarks
16
+ end
17
+ end
18
+
19
+ def self.down
20
+ drop_table :people
21
+ drop_table :cities
22
+ end
23
+ end