repeated_auto_complete 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.
- data/.gitignore +21 -0
- data/README +102 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/init.rb +3 -0
- data/lib/auto_complete.rb +49 -0
- data/lib/auto_complete_form_builder_helper.rb +38 -0
- data/lib/auto_complete_macros_helper.rb +152 -0
- data/lib/repeated_auto_complete.rb +4 -0
- data/lib/view_mapper/README +4 -0
- data/lib/view_mapper/has_many_auto_complete_view.rb +88 -0
- data/lib/view_mapper/templates/controller.rb +90 -0
- data/lib/view_mapper/templates/layout.html.erb +19 -0
- data/lib/view_mapper/templates/style.css +82 -0
- data/lib/view_mapper/templates/view_child_form.html.erb +16 -0
- data/lib/view_mapper/templates/view_form.html.erb +24 -0
- data/rails/init.rb +3 -0
- data/repeated_auto_complete.gemspec +78 -0
- data/test/auto_complete_form_builder_helper_test.rb +123 -0
- data/test/auto_complete_nested_attributes_test.rb +143 -0
- data/test/auto_complete_test.rb +136 -0
- data/test/helper.rb +14 -0
- data/test/view_mapper/expected_templates/_form.html.erb +26 -0
- data/test/view_mapper/expected_templates/_person.html.erb +22 -0
- data/test/view_mapper/expected_templates/create_parents.rb +16 -0
- data/test/view_mapper/expected_templates/edit.html.erb +11 -0
- data/test/view_mapper/expected_templates/index.html.erb +20 -0
- data/test/view_mapper/expected_templates/new.html.erb +10 -0
- data/test/view_mapper/expected_templates/parent.rb +15 -0
- data/test/view_mapper/expected_templates/show.html.erb +37 -0
- data/test/view_mapper/expected_templates/testies_controller.rb +92 -0
- data/test/view_mapper/has_many_auto_complete_view_test.rb +587 -0
- metadata +93 -0
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# Note: These tests require nested attributes (Rails 2.3 or greater).
|
4
|
+
|
5
|
+
Object.const_set("ParentTestModel", Class.new(ActiveRecord::Base))
|
6
|
+
Object.const_set("ChildTestModel", Class.new(ActiveRecord::Base))
|
7
|
+
|
8
|
+
ActiveRecord::Base.connection.create_table :parent_test_models, :force => true do |table|
|
9
|
+
table.column :name, :string
|
10
|
+
end
|
11
|
+
|
12
|
+
ActiveRecord::Base.connection.create_table :child_test_models, :force => true do |table|
|
13
|
+
table.column :name, :string
|
14
|
+
end
|
15
|
+
|
16
|
+
ParentTestModel.class_eval do
|
17
|
+
has_many :child_test_models
|
18
|
+
accepts_nested_attributes_for :child_test_models, :allow_destroy => true
|
19
|
+
end
|
20
|
+
|
21
|
+
ChildTestModel.class_eval do
|
22
|
+
belongs_to :parent_test_model
|
23
|
+
end
|
24
|
+
|
25
|
+
class AutoCompleteNestedAttributesTest < Test::Unit::TestCase
|
26
|
+
|
27
|
+
include AutoCompleteMacrosHelper
|
28
|
+
include ActionView::Helpers::UrlHelper
|
29
|
+
include ActionView::Helpers::TagHelper
|
30
|
+
include ActionView::Helpers::FormHelper
|
31
|
+
|
32
|
+
def setup
|
33
|
+
|
34
|
+
@parent = ParentTestModel.new :name => 'Name of existing parent model'
|
35
|
+
3.times do |i|
|
36
|
+
@parent.child_test_models.build :name => "Name of child model #{i}"
|
37
|
+
end
|
38
|
+
|
39
|
+
controller_class = Class.new do
|
40
|
+
def url_for(options)
|
41
|
+
url = "http://www.example.com/"
|
42
|
+
url << options[:action].to_s if options and options[:action]
|
43
|
+
url
|
44
|
+
end
|
45
|
+
end
|
46
|
+
@controller = controller_class.new
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_nested_attributes_all_have_different_ids
|
51
|
+
id_attribute_pattern = /id=\"[^\"]*\"/i
|
52
|
+
_erbout = []
|
53
|
+
fields_for @parent do |parent_form|
|
54
|
+
parent_form.fields_for :child_test_models do |child_form|
|
55
|
+
_erbout << child_form.text_field_with_auto_complete(:name, {}, { :method => :get })
|
56
|
+
end
|
57
|
+
end
|
58
|
+
assert_equal [], _erbout[0].scan(id_attribute_pattern) & _erbout[1].scan(id_attribute_pattern)
|
59
|
+
assert_equal [], _erbout[0].scan(id_attribute_pattern) & _erbout[2].scan(id_attribute_pattern)
|
60
|
+
assert_equal [], _erbout[1].scan(id_attribute_pattern) & _erbout[2].scan(id_attribute_pattern)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_ajax_url
|
64
|
+
_erbout = ''
|
65
|
+
fields_for @parent do |parent_form|
|
66
|
+
parent_form.fields_for :child_test_models do |child_form|
|
67
|
+
_erbout.concat child_form.text_field_with_auto_complete(:name, {}, { :method => :get })
|
68
|
+
end
|
69
|
+
end
|
70
|
+
assert _erbout.index('http://www.example.com/auto_complete_for_child_test_model_name')
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_ajax_param
|
74
|
+
_erbout = ''
|
75
|
+
fields_for @parent do |parent_form|
|
76
|
+
parent_form.fields_for :child_test_models do |child_form|
|
77
|
+
_erbout.concat child_form.text_field_with_auto_complete(:name, {}, { :method => :get })
|
78
|
+
end
|
79
|
+
end
|
80
|
+
assert _erbout.index("paramName:'child_test_model[name]'")
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_object_value
|
84
|
+
_erbout = ''
|
85
|
+
fields_for @parent do |parent_form|
|
86
|
+
parent_form.fields_for :child_test_models do |child_form|
|
87
|
+
_erbout.concat child_form.text_field_with_auto_complete(:name, {}, { :method => :get })
|
88
|
+
end
|
89
|
+
end
|
90
|
+
3.times do |i|
|
91
|
+
assert _erbout.index("value=\"Name of child model #{i}\"")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_sanitized_object_name
|
96
|
+
fields_for @parent do |parent_form|
|
97
|
+
assert_equal 'parent_test_model',
|
98
|
+
parent_form.sanitized_object_name
|
99
|
+
parent_form.fields_for :child_test_models, { :child_index => 1234 } do |child_form|
|
100
|
+
assert_equal 'parent_test_model_child_test_models_attributes_1234',
|
101
|
+
child_form.sanitized_object_name
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_is_used_as_nested_attribute
|
108
|
+
fields_for @parent do |parent_form|
|
109
|
+
assert !parent_form.is_used_as_nested_attribute?
|
110
|
+
parent_form.fields_for :child_test_models do |child_form|
|
111
|
+
assert child_form.is_used_as_nested_attribute?
|
112
|
+
end
|
113
|
+
end
|
114
|
+
fields_for 'parent[child_test_models_attributes][]', @parent do |rails_2_2_form|
|
115
|
+
assert !rails_2_2_form.is_used_as_nested_attribute?
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_child_index_fields_for_option
|
120
|
+
_erbout = ''
|
121
|
+
fields_for @parent, { :child_index => 5678 } do |parent_form|
|
122
|
+
_erbout.concat parent_form.text_field_with_auto_complete(:name, {}, { :method => :get })
|
123
|
+
assert _erbout.index('parent_test_model_5678_name')
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_child_index_completion_option
|
128
|
+
_erbout = ''
|
129
|
+
fields_for @parent do |parent_form|
|
130
|
+
_erbout.concat parent_form.text_field_with_auto_complete(:name, {}, { :method => :get, :child_index => 1234 })
|
131
|
+
assert _erbout.index('parent_test_model_1234_name')
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_child_index_completion_option_overrides_fields_for_option
|
136
|
+
_erbout = ''
|
137
|
+
fields_for @parent, { :child_index => 5678 } do |parent_form|
|
138
|
+
_erbout.concat parent_form.text_field_with_auto_complete(:name, {}, { :method => :get, :child_index => 1234 })
|
139
|
+
assert _erbout.index('parent_test_model_1234_name')
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
ActionController::Routing::Routes.draw do |map|
|
4
|
+
map.connect ':controller/:action/:id'
|
5
|
+
end
|
6
|
+
|
7
|
+
class AutoCompleteTest < ActionController::TestCase
|
8
|
+
include AutoComplete
|
9
|
+
include AutoCompleteMacrosHelper
|
10
|
+
|
11
|
+
include ActionView::Helpers::UrlHelper
|
12
|
+
include ActionView::Helpers::TagHelper
|
13
|
+
include ActionView::Helpers::TextHelper
|
14
|
+
include ActionView::Helpers::FormHelper
|
15
|
+
include ActionView::Helpers::CaptureHelper
|
16
|
+
include ActionController::Integration
|
17
|
+
|
18
|
+
def setup
|
19
|
+
@controller = Class.new(ActionController::Base) do
|
20
|
+
|
21
|
+
auto_complete_for :some_model, :some_field
|
22
|
+
|
23
|
+
auto_complete_for :some_model, :some_other_field do |items, params|
|
24
|
+
items.scoped( { :conditions => [ "a_third_field = ?", params['some_model']['a_third_field'] ] })
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :items
|
28
|
+
|
29
|
+
def url_for(options)
|
30
|
+
url = "http://www.example.com/"
|
31
|
+
url << options[:action].to_s if options and options[:action]
|
32
|
+
url
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@controller = @controller.new
|
36
|
+
|
37
|
+
Object.const_set("SomeModel", Class.new(ActiveRecord::Base)) unless Object.const_defined?("SomeModel")
|
38
|
+
|
39
|
+
@request = ActionController::TestRequest.new
|
40
|
+
@response = ActionController::TestResponse.new
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def test_auto_complete_field
|
46
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {})\n//]]>\n</script>),
|
47
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" });
|
48
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {tokens:','})\n//]]>\n</script>),
|
49
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" }, :tokens => ',');
|
50
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {tokens:[',']})\n//]]>\n</script>),
|
51
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" }, :tokens => [',']);
|
52
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {minChars:3})\n//]]>\n</script>),
|
53
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" }, :min_chars => 3);
|
54
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {onHide:function(element, update){alert('me');}})\n//]]>\n</script>),
|
55
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" }, :on_hide => "function(element, update){alert('me');}");
|
56
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {frequency:2})\n//]]>\n</script>),
|
57
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" }, :frequency => 2);
|
58
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {afterUpdateElement:function(element,value){alert('You have chosen: '+value)}})\n//]]>\n</script>),
|
59
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" },
|
60
|
+
:after_update_element => "function(element,value){alert('You have chosen: '+value)}");
|
61
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {paramName:'huidriwusch'})\n//]]>\n</script>),
|
62
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" }, :param_name => 'huidriwusch');
|
63
|
+
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nvar some_input_auto_completer = new Ajax.Autocompleter('some_input', 'some_input_auto_complete', 'http://www.example.com/autocomplete', {method:'get'})\n//]]>\n</script>),
|
64
|
+
auto_complete_field("some_input", :url => { :action => "autocomplete" }, :method => :get);
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_auto_complete_result
|
68
|
+
result = [ { :title => 'test1' }, { :title => 'test2' } ]
|
69
|
+
assert_equal %(<ul><li>test1</li><li>test2</li></ul>),
|
70
|
+
auto_complete_result(result, :title)
|
71
|
+
assert_equal %(<ul><li>t<strong class=\"highlight\">est</strong>1</li><li>t<strong class=\"highlight\">est</strong>2</li></ul>),
|
72
|
+
auto_complete_result(result, :title, "est")
|
73
|
+
|
74
|
+
resultuniq = [ { :title => 'test1' }, { :title => 'test1' } ]
|
75
|
+
assert_equal %(<ul><li>t<strong class=\"highlight\">est</strong>1</li></ul>),
|
76
|
+
auto_complete_result(resultuniq, :title, "est")
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_text_field_with_auto_complete
|
80
|
+
assert_match %(<style type="text/css">),
|
81
|
+
text_field_with_auto_complete(:message, :recipient)
|
82
|
+
|
83
|
+
assert_equal %(<input id=\"message_recipient\" name=\"message[recipient]\" size=\"30\" type=\"text\" /><div class=\"auto_complete\" id=\"message_recipient_auto_complete\"></div><script type=\"text/javascript\">\n//<![CDATA[\nvar message_recipient_auto_completer = new Ajax.Autocompleter('message_recipient', 'message_recipient_auto_complete', 'http://www.example.com/auto_complete_for_message_recipient', {})\n//]]>\n</script>),
|
84
|
+
text_field_with_auto_complete(:message, :recipient, {}, :skip_style => true)
|
85
|
+
end
|
86
|
+
|
87
|
+
# auto_complete_for :some_model, :some_field
|
88
|
+
def test_default_auto_complete_for
|
89
|
+
get :auto_complete_for_some_model_some_field, :some_model => { :some_field => "some_value" }
|
90
|
+
default_auto_complete_find_options = @controller.items.proxy_options
|
91
|
+
assert_equal "\"some_models\".some_field ASC", default_auto_complete_find_options[:order]
|
92
|
+
assert_equal 10, default_auto_complete_find_options[:limit]
|
93
|
+
assert_equal ["LOWER(\"some_models\".some_field) LIKE ?", "%some_value%"], default_auto_complete_find_options[:conditions]
|
94
|
+
end
|
95
|
+
|
96
|
+
# auto_complete_for :some_model, :some_other_field do |items, params|
|
97
|
+
# items.scoped( { :conditions => [ "a_third_field = ?", params['some_model']['a_third_field'] ] })
|
98
|
+
# end
|
99
|
+
def test_auto_complete_for_with_block
|
100
|
+
get :auto_complete_for_some_model_some_other_field, :some_model => { :some_other_field => "some_value", :a_third_field => "some_value" }
|
101
|
+
custom_auto_complete_find_options = @controller.items.proxy_options
|
102
|
+
assert_equal [ "a_third_field = ?", 'some_value' ], custom_auto_complete_find_options[:conditions]
|
103
|
+
|
104
|
+
default_auto_complete_scope = @controller.items.proxy_scope
|
105
|
+
assert !default_auto_complete_scope.nil?
|
106
|
+
default_auto_complete_find_options = default_auto_complete_scope.proxy_options
|
107
|
+
assert_equal "\"some_models\".some_other_field ASC", default_auto_complete_find_options[:order]
|
108
|
+
assert_equal 10, default_auto_complete_find_options[:limit]
|
109
|
+
assert_equal ["LOWER(\"some_models\".some_other_field) LIKE ?", "%some_value%"], default_auto_complete_find_options[:conditions]
|
110
|
+
end
|
111
|
+
|
112
|
+
# Quoted table name seems to have changed in Rails 2.3...
|
113
|
+
# For Rails 2.2 or earlier:
|
114
|
+
|
115
|
+
# def test_default_auto_complete_for
|
116
|
+
# get :auto_complete_for_some_model_some_field, :some_model => { :some_field => "some_value" }
|
117
|
+
# default_auto_complete_find_options = @controller.items.proxy_options
|
118
|
+
# assert_equal "`some_models`.some_field ASC", default_auto_complete_find_options[:order]
|
119
|
+
# assert_equal 10, default_auto_complete_find_options[:limit]
|
120
|
+
# assert_equal ["LOWER(`some_models`.some_field) LIKE ?", "%some_value%"], default_auto_complete_find_options[:conditions]
|
121
|
+
# end
|
122
|
+
|
123
|
+
# def test_auto_complete_for_with_block
|
124
|
+
# get :auto_complete_for_some_model_some_other_field, :some_model => { :some_other_field => "some_value", :a_third_field => "some_value" }
|
125
|
+
# custom_auto_complete_find_options = @controller.items.proxy_options
|
126
|
+
# assert_equal [ "a_third_field = ?", 'some_value' ], custom_auto_complete_find_options[:conditions]
|
127
|
+
#
|
128
|
+
# default_auto_complete_scope = @controller.items.proxy_scope
|
129
|
+
# assert !default_auto_complete_scope.nil?
|
130
|
+
# default_auto_complete_find_options = default_auto_complete_scope.proxy_options
|
131
|
+
# assert_equal "`some_models`.some_other_field ASC", default_auto_complete_find_options[:order]
|
132
|
+
# assert_equal 10, default_auto_complete_find_options[:limit]
|
133
|
+
# assert_equal ["LOWER(`some_models`.some_other_field) LIKE ?", "%some_value%"], default_auto_complete_find_options[:conditions]
|
134
|
+
# end
|
135
|
+
|
136
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'action_controller'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'repeated_auto_complete'
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'init')
|
10
|
+
|
11
|
+
class Test::Unit::TestCase
|
12
|
+
end
|
13
|
+
|
14
|
+
ActiveRecord::Base.establish_connection({ :adapter => 'sqlite3', :database => ':memory:' })
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%= f.error_messages %>
|
2
|
+
|
3
|
+
<p>
|
4
|
+
<%= f.label :name %><br />
|
5
|
+
<%= f.text_field_with_auto_complete :name, {}, { :method => :get, :skip_style => true } %>
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<div id='some_other_model_children'>
|
9
|
+
<% f.fields_for :some_other_models do |some_other_model_form| %>
|
10
|
+
<%= render :partial => 'some_other_model', :locals => { :f => some_other_model_form } %>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<p>
|
15
|
+
<%= add_child_link 'Add a SomeOtherModel', 'some_other_model', f %>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<div id='testy_children'>
|
19
|
+
<% f.fields_for :testies do |testy_form| %>
|
20
|
+
<%= render :partial => 'testy', :locals => { :f => testy_form } %>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<p>
|
25
|
+
<%= add_child_link 'Add a Testy', 'testy', f %>
|
26
|
+
</p>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div class="child">
|
2
|
+
<p>
|
3
|
+
Testy <%= f.label :first_name %><br />
|
4
|
+
<%= f.text_field_with_auto_complete :first_name, {}, { :method => :get, :skip_style => true } %>
|
5
|
+
</p>
|
6
|
+
<p>
|
7
|
+
Testy <%= f.label :last_name %><br />
|
8
|
+
<%= f.text_field_with_auto_complete :last_name, {}, { :method => :get, :skip_style => true } %>
|
9
|
+
</p>
|
10
|
+
<p>
|
11
|
+
Testy <%= f.label :address %><br />
|
12
|
+
<%= f.text_field_with_auto_complete :address, {}, { :method => :get, :skip_style => true } %>
|
13
|
+
</p>
|
14
|
+
<p>
|
15
|
+
Testy <%= f.label :some_flag %><br />
|
16
|
+
<%= f.check_box :some_flag %>
|
17
|
+
</p>
|
18
|
+
<p>
|
19
|
+
<%= f.hidden_field :_delete, :class => 'delete' %>
|
20
|
+
<%= remove_child_link 'remove', f %>
|
21
|
+
</p>
|
22
|
+
</div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateParents < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :parents do |t|
|
4
|
+
t.string :first_name
|
5
|
+
t.string :last_name
|
6
|
+
t.string :address
|
7
|
+
t.boolean :some_flag
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :parents
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<h1>Listing parents</h1>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th>Name</th>
|
6
|
+
</tr>
|
7
|
+
|
8
|
+
<% @parents.each do |parent| %>
|
9
|
+
<tr>
|
10
|
+
<td><%=h parent.name %></td>
|
11
|
+
<td><%= link_to 'Show', parent %></td>
|
12
|
+
<td><%= link_to 'Edit', edit_parent_path(parent) %></td>
|
13
|
+
<td><%= link_to 'Destroy', parent, :confirm => 'Are you sure?', :method => :delete %></td>
|
14
|
+
</tr>
|
15
|
+
<% end %>
|
16
|
+
</table>
|
17
|
+
|
18
|
+
<br />
|
19
|
+
|
20
|
+
<%= link_to 'New parent', new_parent_path %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Parent < ActiveRecord::Base
|
2
|
+
has_many :some_other_models
|
3
|
+
has_many :testies
|
4
|
+
accepts_nested_attributes_for :some_other_models,
|
5
|
+
:allow_destroy => true,
|
6
|
+
:reject_if => proc { |attrs| attrs['name'].blank? }
|
7
|
+
accepts_nested_attributes_for :testies,
|
8
|
+
:allow_destroy => true,
|
9
|
+
:reject_if => proc { |attrs|
|
10
|
+
attrs['first_name'].blank? &&
|
11
|
+
attrs['last_name'].blank? &&
|
12
|
+
attrs['address'].blank? &&
|
13
|
+
attrs['some_flag'].blank?
|
14
|
+
}
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<p>
|
2
|
+
<b>Name:</b>
|
3
|
+
<%=h @parent.name %>
|
4
|
+
</p>
|
5
|
+
|
6
|
+
<% @parent.some_other_models.each do |some_other_model| %>
|
7
|
+
<div class="child">
|
8
|
+
<p>
|
9
|
+
<b>SomeOtherModel Name:</b>
|
10
|
+
<%=h some_other_model.name %>
|
11
|
+
</p>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% @parent.testies.each do |testy| %>
|
16
|
+
<div class="child">
|
17
|
+
<p>
|
18
|
+
<b>Testy First name:</b>
|
19
|
+
<%=h testy.first_name %>
|
20
|
+
</p>
|
21
|
+
<p>
|
22
|
+
<b>Testy Last name:</b>
|
23
|
+
<%=h testy.last_name %>
|
24
|
+
</p>
|
25
|
+
<p>
|
26
|
+
<b>Testy Address:</b>
|
27
|
+
<%=h testy.address %>
|
28
|
+
</p>
|
29
|
+
<p>
|
30
|
+
<b>Testy Some flag:</b>
|
31
|
+
<%=h testy.some_flag %>
|
32
|
+
</p>
|
33
|
+
</div>
|
34
|
+
<% end %>
|
35
|
+
|
36
|
+
<%= link_to 'Edit', edit_parent_path(@parent) %> |
|
37
|
+
<%= link_to 'Back', parents_path %>
|