dry_crud 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +31 -12
- data/Rakefile +15 -5
- data/VERSION +1 -1
- data/lib/generators/dry_crud/templates/app/controllers/crud_controller.rb +37 -20
- data/lib/generators/dry_crud/templates/app/helpers/standard_form_builder.rb +17 -12
- data/lib/generators/dry_crud/templates/app/helpers/standard_helper.rb +23 -23
- data/lib/generators/dry_crud/templates/app/helpers/standard_table_builder.rb +11 -3
- data/lib/generators/dry_crud/templates/app/views/crud/_search.html.erb +6 -0
- data/lib/generators/dry_crud/templates/app/views/crud/index.html.erb +2 -0
- data/lib/generators/dry_crud/templates/test/crud_test_model.rb +10 -2
- data/lib/generators/dry_crud/templates/test/custom_assertions.rb +59 -0
- data/lib/generators/dry_crud/templates/test/functional/crud_controller_test_helper.rb +18 -7
- data/lib/generators/dry_crud/templates/test/functional/crud_test_models_controller_test.rb +6 -1
- data/lib/generators/dry_crud/templates/test/unit/custom_assertions_test.rb +95 -0
- data/lib/generators/dry_crud/templates/test/unit/{crud_helper_test.rb → helpers/crud_helper_test.rb} +0 -0
- data/lib/generators/dry_crud/templates/test/unit/{render_inheritable_test.rb → helpers/render_inheritable_test.rb} +0 -0
- data/lib/generators/dry_crud/templates/test/unit/{standard_form_builder_test.rb → helpers/standard_form_builder_test.rb} +31 -2
- data/lib/generators/dry_crud/templates/test/unit/{standard_helper_test.rb → helpers/standard_helper_test.rb} +25 -6
- data/lib/generators/dry_crud/templates/test/unit/{standard_table_builder_test.rb → helpers/standard_table_builder_test.rb} +0 -0
- data/test/templates/app/controllers/people_controller.rb +4 -0
- data/test/templates/app/helpers/people_helper.rb +2 -1
- data/test/templates/app/views/ajax/index.html.erb +1 -6
- data/test/templates/app/views/layouts/crud.html.erb +26 -0
- data/test/templates/app/views/people/_attrs.html.erb +7 -0
- metadata +14 -10
- data/test/templates/app/views/cities/_attrs.html.erb +0 -1
data/README.rdoc
CHANGED
@@ -6,7 +6,7 @@ DRY CRUD generates simple and extendable controller, views and helpers that supp
|
|
6
6
|
|
7
7
|
In order to use the generator, you have to register the gem in your Rails application's +Gemfile+. Add the following lines:
|
8
8
|
|
9
|
-
group :development
|
9
|
+
group :development do
|
10
10
|
gem 'dry_crud'
|
11
11
|
end
|
12
12
|
|
@@ -98,6 +98,16 @@ In <tt>app/helpers/people.rb</tt>:
|
|
98
98
|
By the way: The method +:f+ in +StandardHelper+ uniformly formats arbitrary values according to their class.
|
99
99
|
|
100
100
|
|
101
|
+
==== Filtering the index list
|
102
|
+
|
103
|
+
There is a simple search functionality (based on SQL LIKE queries) implemented in the +CrudController+. Define an array of columns in your controller's +search_columns+ class variable to make the entries searchable by these fields:
|
104
|
+
|
105
|
+
In <tt>app/controllers/people_controller.rb</tt>:
|
106
|
+
self.search_columns = [:firstname, :lastname]
|
107
|
+
|
108
|
+
If you have columns defined, a search box will be displayed in the index view that let's you filter the displayed entries.
|
109
|
+
|
110
|
+
|
101
111
|
==== CRUD controller callbacks
|
102
112
|
|
103
113
|
As a last example, let's say we have added a custom input field that must specially processed. Instead of overwriting the entire update action, it is possible to register callbacks for the +create+, +update+, +save+ (= +create+ and +update+) and +destroy+ actions. They work very similarliy like the callbacks on ActiveRecord. For each action, before and after callbacks are run. Before callbacks may also prevent the action from being executed when returning false. Here is some code:
|
@@ -112,7 +122,7 @@ In <tt>app/controllers/people_controller.rb</tt>:
|
|
112
122
|
|
113
123
|
def delete_picture
|
114
124
|
if !perform_delete_picture(@entry.picture)
|
115
|
-
flash[:
|
125
|
+
flash[:alert] = 'Could not delete picture'
|
116
126
|
false
|
117
127
|
end
|
118
128
|
end
|
@@ -120,7 +130,7 @@ In <tt>app/controllers/people_controller.rb</tt>:
|
|
120
130
|
|
121
131
|
=== Standard Tables and Forms
|
122
132
|
|
123
|
-
DRY CRUD also provides two builder classes for update/create forms and tables for displaying entries of one model. They may be used all over your application to DRY up the form and table code. Normally, they are used with the corresponding methods from +StandardHelper+.
|
133
|
+
DRY CRUD also provides two builder classes for update/create forms and tables for displaying entries of one model. They may be used all over your application to DRY up the form and table code. Normally, they are used with the corresponding methods from +StandardHelper+. When you define a view for a subclass of +CrudController+, you may also use the slightly enhanced +crud_table+ and +crud_form+ methods from +CrudHelper+.
|
124
134
|
|
125
135
|
==== Tables
|
126
136
|
|
@@ -129,13 +139,13 @@ This is the code to define a table with some attribute columns for a list of sam
|
|
129
139
|
t.attrs :lastname, :firstname
|
130
140
|
end %>
|
131
141
|
|
132
|
-
If entries is empty, a basic 'No entries
|
142
|
+
If entries is empty, a basic 'No entries found' message is rendered instead of the table.
|
133
143
|
|
134
144
|
To render custom columns, use the :col method:
|
135
145
|
<%= table(@people) do |t|
|
136
146
|
t.attrs :lastname, :firstname
|
137
147
|
t.col('', :class => 'center') {|entry| image_tag(entry.picture) }
|
138
|
-
t.attrs :street
|
148
|
+
t.attrs :street
|
139
149
|
t.col('Map') {|entry| link_to(entry.city, "http://maps.google.com/?q=#{entry.city}" }
|
140
150
|
end %>
|
141
151
|
|
@@ -143,18 +153,23 @@ To render custom columns, use the :col method:
|
|
143
153
|
|
144
154
|
Forms work very similar. In the most simple case, you just have to specify which attributes of a model to create input fields for, and you get a complete form with error messages, labeled input fields according the column types and a save button:
|
145
155
|
|
146
|
-
|
156
|
+
<%= standard_form(@person, [:firstname, :lastname, :age, :city] -%>
|
147
157
|
|
148
158
|
Of course, custom input fields may be defined as well:
|
149
|
-
|
159
|
+
<%= standard_form(@person, [], :url => {:action => 'custom_update', :id => @person.id}) do |f| %>
|
150
160
|
<%= f.labeled_input_fields :firstname, :lastname %>
|
151
|
-
|
161
|
+
<%= f.labeled(:sex) do %>
|
152
162
|
<%= f.radio_button :sex, true %> female
|
153
163
|
<%= f.radio_button :sex, false %> male
|
154
|
-
<% end
|
164
|
+
<% end %>
|
155
165
|
<%= f.labeled_integer_field :age %>
|
156
166
|
<%= f.labeled_file_field :picture %>
|
157
|
-
<% end
|
167
|
+
<% end %>
|
168
|
+
|
169
|
+
Even +belongs_to+ associations are automatically rendered with a select field. By default, all entries from the associated model are used as options. To customize this, either define an instance variable with the same name as the association in your controller, or pass a <tt>:list</tt> option:
|
170
|
+
<%= f.belongs_to_field :hometown, :list => City.where('country = ?', @person.country) %>
|
171
|
+
|
172
|
+
Yes, it's bad practice to use finder logic in your views! Define the variable <tt>@hometowns</tt> in your controller instead, and you do not even have to specify the <tt>:list</tt> option.
|
158
173
|
|
159
174
|
== Generated Files
|
160
175
|
|
@@ -180,10 +195,12 @@ All generated files are supposed to provide a reasonable foundation for the CRUD
|
|
180
195
|
|
181
196
|
=== Views:
|
182
197
|
|
183
|
-
views/crud/index.html.erb:: The index view displaying a table with all entries and an action link to add new ones.
|
198
|
+
views/crud/index.html.erb:: The index view displaying a table with all entries and an action link to add new ones. If you have +search_columns+ defined for your controller, then a search box is rendered as well.
|
184
199
|
|
185
200
|
views/crud/_list.html.erb:: A partial defining the table in the index view. To change the displayed attributes in your CRUD model, just create an own _list.html.erb in your models view directory.
|
186
201
|
|
202
|
+
views/crud/_search.html.erb:: A partial defining a simple search form that is displayed when +search_columns+ are defined in a subclassing controller.
|
203
|
+
|
187
204
|
views/crud/show.html.erb:: The show view displaying all the attributes of one entry and the various actions to perform on it.
|
188
205
|
|
189
206
|
views/crud/_attrs.html.erb:: A partial defining the attributes to be displayed in the show view.
|
@@ -203,7 +220,9 @@ public/stylesheets/crud.css:: A simple CSS with all the classes and ids used in
|
|
203
220
|
|
204
221
|
=== Tests:
|
205
222
|
|
206
|
-
test/crud_test_model.rb:: A dummy model to run CRUD tests against.
|
223
|
+
{test/crud_test_model.rb}[http://codez.ch/dry_crud/?q=CrudTestHelper]:: A dummy model to run CRUD tests against.
|
224
|
+
|
225
|
+
{test/custom_assertions.rb}[http://codez.ch/dry_crud/?q=CustomAssertions]:: A handful of convenient assertions. Include this module into your <tt>test_helper.rb</tt> file.
|
207
226
|
|
208
227
|
{test/functionals/crud_controller_test_helper.rb}[http://codez.ch/dry_crud/?q=CrudControllerTestHelper]:: A module to include into the functional tests for your CrudController subclasses. Contains a handful of CRUD functionality tests for the provided implementation. So for each new CRUD controller, you get 20 tests for free.
|
209
228
|
|
data/Rakefile
CHANGED
@@ -67,15 +67,15 @@ desc "Install dry_crud as a local gem."
|
|
67
67
|
task :install => [:package] do
|
68
68
|
sudo = RUBY_PLATFORM =~ /win32/ ? '' : 'sudo'
|
69
69
|
gem = RUBY_PLATFORM =~ /java/ ? 'jgem' : 'gem'
|
70
|
-
sh %{#{sudo} #{gem} install --no-ri pkg/dry_crud-#{File.read('VERSION').strip}}
|
70
|
+
sh %{#{sudo} #{gem} install --no-ri pkg/dry_crud-#{File.read('VERSION').strip}.gem}
|
71
71
|
end
|
72
72
|
|
73
73
|
desc "Deploy rdoc to website"
|
74
74
|
task :site => :rdoc do
|
75
75
|
if ENV['DEST']
|
76
|
-
|
76
|
+
sh "rsync -rzv rdoc/ #{ENV['DEST']}"
|
77
77
|
else
|
78
|
-
|
78
|
+
puts "Please specify a destination with DEST=user@server:/deploy/dir"
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -100,10 +100,20 @@ Rake::RDocTask.new do |rdoc|
|
|
100
100
|
list.exclude(/(^|[^.a-z])[a-z]+/)
|
101
101
|
list.exclude('TODO')
|
102
102
|
end.to_a)
|
103
|
-
rdoc.rdoc_files.include('generators/dry_crud/templates/**/*.rb')
|
104
|
-
rdoc.rdoc_files.exclude('generators/dry_crud/templates/**/*_test.rb')
|
103
|
+
rdoc.rdoc_files.include('lib/generators/dry_crud/templates/**/*.rb')
|
104
|
+
rdoc.rdoc_files.exclude('lib/generators/dry_crud/templates/**/*_test.rb')
|
105
105
|
rdoc.rdoc_files.exclude('TODO')
|
106
106
|
|
107
107
|
rdoc.rdoc_dir = 'rdoc'
|
108
108
|
rdoc.main = 'README.rdoc'
|
109
109
|
end
|
110
|
+
|
111
|
+
desc "Outputs the commands required for a release. Does not perform any other actions"
|
112
|
+
task :release do
|
113
|
+
version = File.read('VERSION').strip
|
114
|
+
puts "Issue the following commands to perform a release:"
|
115
|
+
puts " $ git tag version-#{version}"
|
116
|
+
puts " $ git push --tags"
|
117
|
+
puts " $ rake repackage"
|
118
|
+
puts " $ gem push pkg/dry_crud-#{version}.gem"
|
119
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
@@ -8,6 +8,22 @@ class CrudController < ApplicationController
|
|
8
8
|
|
9
9
|
include RenderInheritable
|
10
10
|
|
11
|
+
# Set up entry object to use in the various actions.
|
12
|
+
before_filter :build_entry, :only => [:new, :create]
|
13
|
+
before_filter :set_entry, :only => [:show, :edit, :update, :destroy]
|
14
|
+
|
15
|
+
helper :standard
|
16
|
+
helper_method :model_class, :models_label, :full_entry_label, :search_support?
|
17
|
+
|
18
|
+
delegate :model_class, :model_identifier, :models_label, :to => 'self.class'
|
19
|
+
|
20
|
+
hide_action :model_class, :models_label, :model_identifier, :run_callbacks, :inheritable_root_controller
|
21
|
+
|
22
|
+
# Define an array of searchable columns in your subclassing controllers.
|
23
|
+
class_attribute :search_columns
|
24
|
+
self.search_columns = []
|
25
|
+
|
26
|
+
# Callbacks
|
11
27
|
extend ActiveModel::Callbacks
|
12
28
|
|
13
29
|
# Defines before and after callback hooks for create, update, save and destroy.
|
@@ -20,9 +36,7 @@ class CrudController < ApplicationController
|
|
20
36
|
:render_edit,
|
21
37
|
:only => :before,
|
22
38
|
:terminator => "result == false || performed?"
|
23
|
-
|
24
|
-
delegate :model_class, :model_identifier, :models_label, :to => 'self.class'
|
25
|
-
|
39
|
+
|
26
40
|
# Verify that required :id param is present and only allow good http methods.
|
27
41
|
# Uncomment if you have the Rails verification plugin installed.
|
28
42
|
#verify :params => :id, :only => :show, :redirect_to => { :action => 'index' }
|
@@ -30,15 +44,6 @@ class CrudController < ApplicationController
|
|
30
44
|
#verify :method => [:put, :post], :params => :id, :only => :update, :redirect_to => { :action => 'index' }
|
31
45
|
#verify :method => [:delete, :post], :params => :id, :only => :destroy, :redirect_to => { :action => 'index' }
|
32
46
|
|
33
|
-
# Set up entry object to use in the various actions.
|
34
|
-
before_filter :build_entry, :only => [:new, :create]
|
35
|
-
before_filter :set_entry, :only => [:show, :edit, :update, :destroy]
|
36
|
-
|
37
|
-
helper :standard
|
38
|
-
helper_method :model_class, :models_label, :full_entry_label
|
39
|
-
|
40
|
-
hide_action :model_class, :models_label, :model_identifier, :run_callbacks, :inheritable_root_controller
|
41
|
-
|
42
47
|
|
43
48
|
############## ACTIONS ############################################
|
44
49
|
|
@@ -143,16 +148,28 @@ class CrudController < ApplicationController
|
|
143
148
|
# Sets an existing model entry from the given id.
|
144
149
|
def set_entry
|
145
150
|
@entry = model_class.find(params[:id])
|
146
|
-
end
|
151
|
+
end
|
147
152
|
|
148
153
|
# A label for the current entry, including the model name.
|
149
|
-
def full_entry_label
|
150
|
-
|
151
|
-
end
|
154
|
+
def full_entry_label
|
155
|
+
"#{models_label.singularize} '#{@entry.label}'"
|
156
|
+
end
|
152
157
|
|
153
158
|
# Find options used in the index action.
|
154
159
|
def find_all_options
|
155
|
-
{}
|
160
|
+
{ :conditions => search_condition }
|
161
|
+
end
|
162
|
+
|
163
|
+
def search_condition
|
164
|
+
if search_support? && params[:q].present?
|
165
|
+
clause = search_columns.collect {|f| "#{f} LIKE ?" }.join(" OR ")
|
166
|
+
param = "%#{params[:q]}%"
|
167
|
+
["(#{clause})"] + [param] * search_columns.size
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def search_support?
|
172
|
+
search_columns.present?
|
156
173
|
end
|
157
174
|
|
158
175
|
# Redirects to the show action of a single entry.
|
@@ -162,7 +179,7 @@ class CrudController < ApplicationController
|
|
162
179
|
|
163
180
|
# Redirects to the main action of this controller.
|
164
181
|
def redirect_to_index
|
165
|
-
redirect_to
|
182
|
+
redirect_to polymorphic_path(model_class)
|
166
183
|
end
|
167
184
|
|
168
185
|
# Helper method to run before_render callbacks and render the action.
|
@@ -173,9 +190,9 @@ class CrudController < ApplicationController
|
|
173
190
|
end
|
174
191
|
|
175
192
|
# Saves the current entry with callbacks.
|
176
|
-
def save_entry
|
193
|
+
def save_entry
|
177
194
|
with_callbacks(:save) { @entry.save }
|
178
|
-
end
|
195
|
+
end
|
179
196
|
|
180
197
|
# Helper method the run the given block in between the before and after
|
181
198
|
# callbacks of the given kind.
|
@@ -9,12 +9,12 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
9
9
|
|
10
10
|
attr_reader :template
|
11
11
|
|
12
|
-
delegate :association, :
|
12
|
+
delegate :association, :column_type, :column_property, :captionize,
|
13
13
|
:to => :template
|
14
14
|
|
15
15
|
# Render multiple input fields together with a label for the given attributes.
|
16
16
|
def labeled_input_fields(*attrs)
|
17
|
-
attrs.collect {|a| labeled_input_field(a) }.join("\n")
|
17
|
+
attrs.collect {|a| labeled_input_field(a) }.join("\n").html_safe
|
18
18
|
end
|
19
19
|
|
20
20
|
# Render a standartized label.
|
@@ -126,17 +126,11 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
126
126
|
|
127
127
|
protected
|
128
128
|
|
129
|
-
|
130
|
-
|
131
|
-
if name.to_s.start_with?(prefix)
|
132
|
-
field_method = name.to_s[prefix.size..-1]
|
133
|
-
field_method if respond_to?(field_method)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
129
|
+
# Returns true if attr is a non-polymorphic belongs_to association,
|
130
|
+
# for which an input field may be automatically rendered.
|
137
131
|
def belongs_to_association?(attr, type)
|
138
132
|
if type == :integer || type == nil
|
139
|
-
assoc =
|
133
|
+
assoc = association(@object, attr, :belongs_to)
|
140
134
|
assoc.present? && assoc.options[:polymorphic].nil?
|
141
135
|
else
|
142
136
|
false
|
@@ -152,10 +146,21 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
152
146
|
assoc = association(@object, attr)
|
153
147
|
list = @template.send(:instance_variable_get, :"@#{assoc.name.to_s.pluralize}")
|
154
148
|
unless list
|
155
|
-
list = assoc.klass.
|
149
|
+
list = assoc.klass.all(:conditions => assoc.options[:conditions],
|
156
150
|
:order => assoc.options[:order])
|
157
151
|
end
|
158
152
|
end
|
159
153
|
list
|
160
154
|
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def labeled_field_method?(name)
|
159
|
+
prefix = 'labeled_'
|
160
|
+
if name.to_s.start_with?(prefix)
|
161
|
+
field_method = name.to_s[prefix.size..-1]
|
162
|
+
field_method if respond_to?(field_method)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
161
166
|
end
|
@@ -3,12 +3,12 @@
|
|
3
3
|
# ApplicationController.
|
4
4
|
module StandardHelper
|
5
5
|
|
6
|
-
NO_LIST_ENTRIES_MESSAGE = "No entries
|
6
|
+
NO_LIST_ENTRIES_MESSAGE = "No entries found"
|
7
7
|
CONFIRM_DELETE_MESSAGE = 'Do you really want to delete this entry?'
|
8
8
|
|
9
9
|
FLOAT_FORMAT = "%.2f"
|
10
10
|
TIME_FORMAT = "%H:%M"
|
11
|
-
EMPTY_STRING = " " # non-breaking space asserts better css styling.
|
11
|
+
EMPTY_STRING = " ".html_safe # non-breaking space asserts better css styling.
|
12
12
|
|
13
13
|
################ FORMATTING HELPERS ##################################
|
14
14
|
|
@@ -20,13 +20,13 @@ module StandardHelper
|
|
20
20
|
case value
|
21
21
|
when Fixnum then number_with_delimiter(value)
|
22
22
|
when Float then FLOAT_FORMAT % value
|
23
|
-
|
23
|
+
when Date then value.to_s
|
24
24
|
when Time then value.strftime(TIME_FORMAT)
|
25
25
|
when true then 'yes'
|
26
26
|
when false then 'no'
|
27
27
|
when nil then EMPTY_STRING
|
28
28
|
else
|
29
|
-
value.respond_to?(:label) ?
|
29
|
+
value.respond_to?(:label) ? value.label : value.to_s
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -38,7 +38,7 @@ module StandardHelper
|
|
38
38
|
format_attr_method = :"format_#{attr.to_s}"
|
39
39
|
if respond_to?(format_attr_method)
|
40
40
|
send(format_attr_method, obj)
|
41
|
-
elsif assoc =
|
41
|
+
elsif assoc = association(obj, attr, :belongs_to)
|
42
42
|
format_assoc(obj, assoc)
|
43
43
|
else
|
44
44
|
format_type(obj, attr)
|
@@ -50,7 +50,6 @@ module StandardHelper
|
|
50
50
|
|
51
51
|
|
52
52
|
# Renders an arbitrary content with the given label. Used for uniform presentation.
|
53
|
-
# Without block, this may be used in the form <%= labeled(...) %>, with like <% labeled(..) do %>
|
54
53
|
def labeled(label, content = nil, &block)
|
55
54
|
content = capture(&block) if block_given?
|
56
55
|
render(:partial => 'shared/labeled', :locals => { :label => label, :content => content})
|
@@ -69,12 +68,17 @@ module StandardHelper
|
|
69
68
|
# Optionally surrounded with a div.
|
70
69
|
def render_attrs(obj, attrs, div = true)
|
71
70
|
html = attrs.collect do |a|
|
72
|
-
|
73
|
-
end.join.html_safe
|
71
|
+
labeled_attr(obj, a)
|
72
|
+
end.join("\n").html_safe
|
74
73
|
|
75
74
|
div ? content_tag(:div, html, :class => 'attributes') : html
|
76
75
|
end
|
77
76
|
|
77
|
+
# Renders the formatted content of the given attribute with a label.
|
78
|
+
def labeled_attr(obj, attr)
|
79
|
+
labeled(captionize(attr, obj.class), format_attr(obj, attr))
|
80
|
+
end
|
81
|
+
|
78
82
|
# Renders a table for the given entries. One column is rendered for each attribute passed.
|
79
83
|
# If a block is given, the columns defined therein are appended to the attribute columns.
|
80
84
|
# If entries is empty, an appropriate message is rendered.
|
@@ -142,19 +146,19 @@ module StandardHelper
|
|
142
146
|
end
|
143
147
|
|
144
148
|
# A generic helper method to create action links.
|
145
|
-
# These link
|
149
|
+
# These link could be styled to look like buttons, for example.
|
146
150
|
def link_action(label, options = {}, html_options = {})
|
147
151
|
link_to("[#{label}]", options, {:class => 'action'}.merge(html_options))
|
148
152
|
end
|
149
153
|
|
150
154
|
protected
|
151
155
|
|
152
|
-
# Helper methods that are not
|
156
|
+
# Helper methods that are not directly called from templates.
|
153
157
|
|
154
158
|
# Formats an active record association
|
155
159
|
def format_assoc(obj, assoc)
|
156
160
|
if assoc_val = obj.send(assoc.name)
|
157
|
-
link_to_unless(no_assoc_link?(assoc),
|
161
|
+
link_to_unless(no_assoc_link?(assoc), assoc_val.label, assoc_val)
|
158
162
|
else
|
159
163
|
'(none)'
|
160
164
|
end
|
@@ -194,20 +198,16 @@ module StandardHelper
|
|
194
198
|
end
|
195
199
|
end
|
196
200
|
|
197
|
-
# Returns the :belongs_to association for the given attribute or nil if there is none.
|
198
|
-
def belongs_to_association(obj, attr)
|
199
|
-
if assoc = association(obj, attr)
|
200
|
-
assoc if assoc.macro == :belongs_to
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
201
|
# Returns the association proxy for the given attribute. The attr parameter
|
205
|
-
# may be the _id column or the association name.
|
206
|
-
#
|
207
|
-
|
202
|
+
# may be the _id column or the association name. If a macro (e.g. :belongs_to)
|
203
|
+
# is given, the association must be of this type, otherwise, any association
|
204
|
+
# is returned. Returns nil if no association (or not of the given macro) was
|
205
|
+
# found.
|
206
|
+
def association(obj, attr, macro = nil)
|
208
207
|
if obj.class.respond_to?(:reflect_on_association)
|
209
|
-
|
210
|
-
obj.class.reflect_on_association(
|
208
|
+
name = attr.to_s =~ /_id$/ ? attr.to_s[0..-4].to_sym : attr
|
209
|
+
assoc = obj.class.reflect_on_association(name)
|
210
|
+
assoc if assoc && (macro.nil? || assoc.macro == macro)
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
@@ -10,7 +10,7 @@ class StandardTableBuilder
|
|
10
10
|
|
11
11
|
# Delegate called methods to template.
|
12
12
|
# including StandardHelper would lead to problems with indirectly called methods.
|
13
|
-
delegate :content_tag, :format_attr, :column_type, :
|
13
|
+
delegate :content_tag, :format_attr, :column_type, :association,
|
14
14
|
:captionize, :tr_alt, :to => :template
|
15
15
|
|
16
16
|
def initialize(entries, template)
|
@@ -40,10 +40,18 @@ class StandardTableBuilder
|
|
40
40
|
# the formatted attribute value for the current entry.
|
41
41
|
def attrs(*attrs)
|
42
42
|
attrs.each do |a|
|
43
|
-
|
43
|
+
attr(a)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
# Define a column for the given attribute and an optional header.
|
48
|
+
# If no header is given, the attribute name is used. The cell will
|
49
|
+
# contain the formatted attribute value for the current entry.
|
50
|
+
def attr(a, header = nil)
|
51
|
+
header ||= captionize(a, entry_class)
|
52
|
+
col(header, :class => align_class(a)) { |e| format_attr(e, a) }
|
53
|
+
end
|
54
|
+
|
47
55
|
# Renders the table as HTML.
|
48
56
|
def to_html
|
49
57
|
content_tag :table, :class => 'list' do
|
@@ -57,7 +65,7 @@ class StandardTableBuilder
|
|
57
65
|
entry = entries.first
|
58
66
|
case column_type(entry, attr)
|
59
67
|
when :integer, :float, :decimal
|
60
|
-
'right_align' unless
|
68
|
+
'right_align' unless association(entry, attr, :belongs_to)
|
61
69
|
when :boolean
|
62
70
|
'center_align'
|
63
71
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
class CrudTestModel < ActiveRecord::Base #:nodoc:
|
2
|
-
|
2
|
+
|
3
|
+
validates :name, :presence => true
|
4
|
+
validates :rating, :inclusion => { :in => 1..10 }
|
3
5
|
|
4
|
-
default_scope
|
6
|
+
default_scope order('name')
|
5
7
|
|
6
8
|
belongs_to :companion, :class_name => 'CrudTestModel'
|
7
9
|
|
@@ -13,6 +15,8 @@ end
|
|
13
15
|
class CrudTestModelsController < CrudController #:nodoc:
|
14
16
|
HANDLE_PREFIX = 'handle_'
|
15
17
|
|
18
|
+
self.search_columns = [:name, :whatever, :remarks]
|
19
|
+
|
16
20
|
before_create :possibly_redirect
|
17
21
|
before_create :handle_name
|
18
22
|
|
@@ -24,6 +28,10 @@ class CrudTestModelsController < CrudController #:nodoc:
|
|
24
28
|
|
25
29
|
hide_action :called_callbacks, :should_redirect, :should_redirect=
|
26
30
|
|
31
|
+
# don't use the standard layout as it may require different routes
|
32
|
+
# than just the test route for this controller
|
33
|
+
layout nil
|
34
|
+
|
27
35
|
private
|
28
36
|
|
29
37
|
# custom callback
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# A handful of convenient assertions. The aim of custom assertions is to
|
2
|
+
# provide more specific error messages and to perform complex checks.
|
3
|
+
#
|
4
|
+
# Ideally, include this module into your test_helper.rb file:
|
5
|
+
# # at the beginning of the file:
|
6
|
+
# require 'custom_assertions'
|
7
|
+
#
|
8
|
+
# # inside the class definition:
|
9
|
+
# include CustomAssertions
|
10
|
+
module CustomAssertions
|
11
|
+
|
12
|
+
# Asserts that the element is included in the collection.
|
13
|
+
def assert_include(collection, element, message = "")
|
14
|
+
full_message = build_message(message, "<?> expected to be included in \n<?>.",
|
15
|
+
element, collection)
|
16
|
+
assert_block(full_message) { collection.include?(element) }
|
17
|
+
end
|
18
|
+
|
19
|
+
# Asserts that the element is not included in the collection.
|
20
|
+
def assert_not_include(collection, element, message = "")
|
21
|
+
full_message = build_message(message, "<?> expected not to be included in \n<?>.",
|
22
|
+
element, collection)
|
23
|
+
assert_block(full_message) { !collection.include?(element) }
|
24
|
+
end
|
25
|
+
|
26
|
+
# Asserts that the given active model record is valid.
|
27
|
+
# This method used to be part of Rails but was deprecated, no idea why.
|
28
|
+
def assert_valid(record, message = "")
|
29
|
+
record.valid?
|
30
|
+
full_message = build_message(message,
|
31
|
+
"? expected to be valid, but has the following errors: \n ?.",
|
32
|
+
record, record.errors.full_messages.join("\n"))
|
33
|
+
assert_block(full_message) { record.valid? }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Asserts that the given active model record is not valid.
|
37
|
+
# If you provide a set of invalid attribute symbols, all of and only these
|
38
|
+
# attributes are expected to have errors. If no invalid attributes are
|
39
|
+
# specified, only the invalidity of the record is asserted.
|
40
|
+
def assert_not_valid(record, *invalid_attrs)
|
41
|
+
message = build_message("", "? expected to be invalid, but is valid.", record)
|
42
|
+
assert_block(message) { !record.valid? }
|
43
|
+
|
44
|
+
# assert that the given attributes have errors.
|
45
|
+
invalid_attrs.each do |a|
|
46
|
+
message = build_message("", "Attribute <?> expected to be invalid, but is valid.", a)
|
47
|
+
assert_block(message) { record.errors[a].present? }
|
48
|
+
end
|
49
|
+
|
50
|
+
if invalid_attrs.present?
|
51
|
+
# assert that no other than the invalid attributes have errors.
|
52
|
+
record.errors.each do |a, error|
|
53
|
+
message = build_message("", "Attribute <?> not declared as invalid attribute, but has the following error: \n?.", a, error)
|
54
|
+
assert_block(message) { invalid_attrs.include?(a) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -8,20 +8,31 @@ module CrudControllerTestHelper
|
|
8
8
|
get :index
|
9
9
|
assert_response :success
|
10
10
|
assert_template 'index'
|
11
|
-
|
11
|
+
assert_present assigns(:entries)
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_index_xml
|
15
15
|
get :index, :format => 'xml'
|
16
16
|
assert_response :success
|
17
|
-
|
17
|
+
assert_present assigns(:entries)
|
18
18
|
assert @response.body.starts_with?("<?xml")
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_index_search
|
22
|
+
field = @controller.search_columns.first
|
23
|
+
val = field && test_entry[field].to_s
|
24
|
+
return if val.blank? # does not support search or no value in this field
|
25
|
+
|
26
|
+
get :index, :q => val[0..((val.size + 1)/ 2)]
|
27
|
+
assert_response :success
|
28
|
+
assert_present assigns(:entries)
|
29
|
+
assert assigns(:entries).include?(test_entry)
|
30
|
+
end
|
31
|
+
|
21
32
|
def test_show
|
22
33
|
get :show, :id => test_entry.id
|
23
34
|
assert_response :success
|
24
|
-
assert_template 'show'
|
35
|
+
assert_template 'show'
|
25
36
|
assert_equal test_entry, assigns(:entry)
|
26
37
|
end
|
27
38
|
|
@@ -37,13 +48,13 @@ module CrudControllerTestHelper
|
|
37
48
|
get :show, :id => 9999
|
38
49
|
end
|
39
50
|
end
|
40
|
-
|
51
|
+
|
41
52
|
def test_show_without_id_redirects_to_index
|
42
53
|
assert_raise(ActionController::RoutingError) do
|
43
54
|
get :show
|
44
55
|
end
|
45
56
|
end
|
46
|
-
|
57
|
+
|
47
58
|
def test_new
|
48
59
|
get :new
|
49
60
|
assert_response :success
|
@@ -156,11 +167,11 @@ module CrudControllerTestHelper
|
|
156
167
|
end
|
157
168
|
|
158
169
|
def model_class
|
159
|
-
@controller.
|
170
|
+
@controller.model_class
|
160
171
|
end
|
161
172
|
|
162
173
|
def model_identifier
|
163
|
-
@controller.
|
174
|
+
@controller.model_identifier
|
164
175
|
end
|
165
176
|
|
166
177
|
# Test object used in several tests
|
@@ -29,6 +29,11 @@ class CrudTestModelsControllerTest < ActionController::TestCase
|
|
29
29
|
assert_equal assigns(:entries).sort_by {|a| a.name }, assigns(:entries)
|
30
30
|
end
|
31
31
|
|
32
|
+
def test_index_search
|
33
|
+
super
|
34
|
+
assert_equal 1, assigns(:entries).size
|
35
|
+
end
|
36
|
+
|
32
37
|
def test_new
|
33
38
|
super
|
34
39
|
assert assigns(:companions)
|
@@ -99,7 +104,7 @@ class CrudTestModelsControllerTest < ActionController::TestCase
|
|
99
104
|
{:name => 'foo',
|
100
105
|
:children => 42,
|
101
106
|
:companion_id => 3,
|
102
|
-
:rating =>
|
107
|
+
:rating => 8.5,
|
103
108
|
:income => 2.42,
|
104
109
|
:birthdate => '31-12-1999'.to_date,
|
105
110
|
:human => true,
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'custom_assertions'
|
3
|
+
require 'crud_test_model'
|
4
|
+
|
5
|
+
class CustomAssertionsTest < ActiveSupport::TestCase
|
6
|
+
|
7
|
+
include CustomAssertions
|
8
|
+
|
9
|
+
include CrudTestHelper
|
10
|
+
|
11
|
+
setup :reset_db, :setup_db, :create_test_data
|
12
|
+
teardown :reset_db
|
13
|
+
|
14
|
+
test "assert include succeeds if included" do
|
15
|
+
assert_nothing_raised do
|
16
|
+
assert_include [1,2,3], 2
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
test "assert include succeeds if record included" do
|
21
|
+
assert_nothing_raised do
|
22
|
+
assert_include CrudTestModel.all, crud_test_models("AAAAA")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
test "assert include fails if not included" do
|
27
|
+
assert_raise(Test::Unit::AssertionFailedError) do
|
28
|
+
assert_include [1,2,3], 5
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
test "assert not include succeeds if not included" do
|
33
|
+
assert_nothing_raised do
|
34
|
+
assert_not_include [1,2,3], 5
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
test "assert not include fails if included" do
|
39
|
+
assert_raise(Test::Unit::AssertionFailedError) do
|
40
|
+
assert_not_include [1,2,3], 3
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
test "assert valid record succeeds" do
|
45
|
+
assert_nothing_raised do
|
46
|
+
assert_valid crud_test_models("AAAAA")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
test "assert valid record fails for invalid" do
|
51
|
+
assert_raise(Test::Unit::AssertionFailedError) do
|
52
|
+
assert_valid invalid_record
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
test "assert not valid succeeds if record invalid" do
|
57
|
+
assert_nothing_raised do
|
58
|
+
assert_not_valid invalid_record
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
test "assert not valid succeds if record invalid and invalid attrs given" do
|
63
|
+
assert_nothing_raised do
|
64
|
+
assert_not_valid invalid_record, :name, :rating
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
test "assert not valid fails if record valid" do
|
69
|
+
assert_raise(Test::Unit::AssertionFailedError) do
|
70
|
+
assert_not_valid crud_test_models("AAAAA")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
test "assert not valid fails if record invalid and valid attrs given" do
|
75
|
+
assert_raise(Test::Unit::AssertionFailedError) do
|
76
|
+
assert_not_valid invalid_record, :name, :rating, :children
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
test "assert not valid fails if record invalid and not all invalid attrs given" do
|
81
|
+
assert_raise(Test::Unit::AssertionFailedError) do
|
82
|
+
assert_not_valid invalid_record, :name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def invalid_record
|
89
|
+
m = crud_test_models("AAAAA")
|
90
|
+
m.name = nil
|
91
|
+
m.rating = 42
|
92
|
+
m
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
data/lib/generators/dry_crud/templates/test/unit/{crud_helper_test.rb → helpers/crud_helper_test.rb}
RENAMED
File without changes
|
File without changes
|
@@ -20,26 +20,40 @@ class StandardFormBuilderTest < ActionView::TestCase
|
|
20
20
|
|
21
21
|
test "input_field dispatches string attr to string_field" do
|
22
22
|
assert_equal form.string_field(:name), form.input_field(:name)
|
23
|
+
assert form.string_field(:name).html_safe?
|
23
24
|
end
|
24
25
|
|
25
26
|
test "input_field dispatches text attr to text_area" do
|
26
27
|
assert_equal form.text_area(:remarks), form.input_field(:remarks)
|
28
|
+
assert form.text_area(:remarks).html_safe?
|
27
29
|
end
|
28
30
|
|
29
31
|
test "input_field dispatches integer attr to integer_field" do
|
30
32
|
assert_equal form.integer_field(:children), form.input_field(:children)
|
33
|
+
assert form.integer_field(:children).html_safe?
|
31
34
|
end
|
32
35
|
|
33
36
|
test "input_field dispatches boolean attr to boolean_field" do
|
34
37
|
assert_equal form.boolean_field(:human), form.input_field(:human)
|
38
|
+
assert form.boolean_field(:human).html_safe?
|
35
39
|
end
|
36
40
|
|
37
41
|
test "input_field dispatches date attr to date_field" do
|
38
42
|
assert_equal form.date_field(:birthdate), form.input_field(:birthdate)
|
43
|
+
assert form.date_field(:birthdate).html_safe?
|
39
44
|
end
|
40
45
|
|
41
46
|
test "input_field dispatches belongs_to attr to select field" do
|
42
47
|
assert_equal form.belongs_to_field(:companion_id), form.input_field(:companion_id)
|
48
|
+
assert form.belongs_to_field(:companion_id).html_safe?
|
49
|
+
end
|
50
|
+
|
51
|
+
test "input_fields concats multiple fields" do
|
52
|
+
result = form.labeled_input_fields(:name, :remarks, :children)
|
53
|
+
assert result.html_safe?
|
54
|
+
assert result.include?(form.input_field(:name))
|
55
|
+
assert result.include?(form.input_field(:remarks))
|
56
|
+
assert result.include?(form.input_field(:children))
|
43
57
|
end
|
44
58
|
|
45
59
|
test "belongs_to_field has all options by default" do
|
@@ -70,14 +84,29 @@ class StandardFormBuilderTest < ActionView::TestCase
|
|
70
84
|
assert_no_match /(\<option .*?)/m, f
|
71
85
|
end
|
72
86
|
|
73
|
-
|
74
87
|
test "string_field sets maxlength attribute if limit" do
|
75
88
|
assert_match /maxlength="50"/, form.string_field(:name)
|
76
89
|
end
|
77
90
|
|
78
|
-
test "
|
91
|
+
test "label creates captionized label" do
|
92
|
+
assert_match /label for.+Gugus dada/, form.label(:gugus_dada)
|
93
|
+
assert form.label(:gugus_dada).html_safe?
|
94
|
+
end
|
95
|
+
|
96
|
+
test "classic label still works" do
|
97
|
+
assert_match /label for.+hoho/, form.label(:gugus_dada, "hoho")
|
98
|
+
assert form.label(:gugus_dada, "hoho").html_safe?
|
99
|
+
end
|
100
|
+
|
101
|
+
test "labeled_text_field create label" do
|
79
102
|
assert_match /label for.+input/m, form.labeled_string_field(:name)
|
103
|
+
assert form.labeled_string_field(:name).html_safe?
|
80
104
|
end
|
81
105
|
|
106
|
+
test "labeled field creates label" do
|
107
|
+
result = form.labeled("gugus", "<input type='text' name='gugus' />")
|
108
|
+
assert result.html_safe?
|
109
|
+
assert_match /label for.+input/m, result
|
110
|
+
end
|
82
111
|
|
83
112
|
end
|
@@ -16,25 +16,36 @@ class StandardHelperTest < ActionView::TestCase
|
|
16
16
|
test "labeled text as block" do
|
17
17
|
result = labeled("label") { "value" }
|
18
18
|
|
19
|
+
assert result.html_safe?
|
19
20
|
assert_dom_equal "<div class='labeled'> <div class='caption'>label</div> <div class='value'>value</div> </div>", result.squish
|
20
21
|
end
|
21
22
|
|
22
23
|
test "labeled text empty" do
|
23
24
|
result = labeled("label", "")
|
24
25
|
|
26
|
+
assert result.html_safe?
|
25
27
|
assert_dom_equal "<div class='labeled'> <div class='caption'>label</div> <div class='value'>#{EMPTY_STRING}</div> </div>", result.squish
|
26
28
|
end
|
27
29
|
|
28
30
|
test "labeled text as content" do
|
29
|
-
result = labeled("label", "value")
|
31
|
+
result = labeled("label", "value <unsafe>")
|
30
32
|
|
31
|
-
|
33
|
+
assert result.html_safe?
|
34
|
+
assert_dom_equal "<div class='labeled'> <div class='caption'>label</div> <div class='value'>value <unsafe></div> </div>", result.squish
|
35
|
+
end
|
36
|
+
|
37
|
+
test "labeled attr" do
|
38
|
+
result = labeled_attr('foo', :size)
|
39
|
+
assert result.html_safe?
|
40
|
+
assert_dom_equal "<div class='labeled'> <div class='caption'>Size</div> <div class='value'>3 chars</div> </div>", result.squish
|
32
41
|
end
|
33
42
|
|
34
43
|
test "alternate row" do
|
35
44
|
result_1 = tr_alt { "(test row content)" }
|
36
45
|
result_2 = tr_alt { "(test row content)" }
|
37
46
|
|
47
|
+
assert result_1.html_safe?
|
48
|
+
assert result_2.html_safe?
|
38
49
|
assert_dom_equal "<tr class='even'>(test row content)</tr>", result_1
|
39
50
|
assert_dom_equal "<tr class='odd'>(test row content)</tr>", result_2
|
40
51
|
end
|
@@ -57,12 +68,14 @@ class StandardHelperTest < ActionView::TestCase
|
|
57
68
|
end
|
58
69
|
|
59
70
|
test "format nil" do
|
71
|
+
assert EMPTY_STRING.html_safe?
|
60
72
|
assert_equal EMPTY_STRING, f(nil)
|
61
73
|
end
|
62
74
|
|
63
75
|
test "format Strings" do
|
64
76
|
assert_equal "blah blah", f("blah blah")
|
65
|
-
|
77
|
+
assert_equal "<injection>", f("<injection>")
|
78
|
+
assert !f("<injection>").html_safe?
|
66
79
|
end
|
67
80
|
|
68
81
|
test "format attr with fallthrough to f" do
|
@@ -115,19 +128,25 @@ class StandardHelperTest < ActionView::TestCase
|
|
115
128
|
test "format text column" do
|
116
129
|
m = crud_test_models(:AAAAA)
|
117
130
|
assert_equal "<p>AAAAA AAAAA AAAAA\n<br />AAAAA AAAAA AAAAA\n<br />AAAAA AAAAA AAAAA\n</p>", format_type(m, :remarks)
|
131
|
+
assert format_type(m, :remarks).html_safe?
|
118
132
|
end
|
119
133
|
|
120
134
|
test "empty table should render message" do
|
121
|
-
|
135
|
+
result = table([]) { }
|
136
|
+
assert result.html_safe?
|
137
|
+
assert_dom_equal "<div class='list'>#{NO_LIST_ENTRIES_MESSAGE}</div>", result
|
122
138
|
end
|
123
139
|
|
124
140
|
test "non empty table should render table" do
|
125
|
-
|
141
|
+
result = table(['foo', 'bar']) {|t| t.attrs :size, :upcase }
|
142
|
+
assert result.html_safe?
|
143
|
+
assert_match(/^\<table.*\<\/table\>$/, result)
|
126
144
|
end
|
127
145
|
|
128
146
|
test "table with attrs" do
|
129
147
|
expected = StandardTableBuilder.table(['foo', 'bar'], self) { |t| t.attrs :size, :upcase }
|
130
148
|
actual = table(['foo', 'bar'], :size, :upcase)
|
149
|
+
assert actual.html_safe?
|
131
150
|
assert_equal expected, actual
|
132
151
|
end
|
133
152
|
|
@@ -135,6 +154,7 @@ class StandardHelperTest < ActionView::TestCase
|
|
135
154
|
assert_equal "Camel Case", captionize(:camel_case)
|
136
155
|
assert_equal "All Upper Case", captionize("all upper case")
|
137
156
|
assert_equal "With Object", captionize("With object", Object.new)
|
157
|
+
assert !captionize('bad <title>').html_safe?
|
138
158
|
end
|
139
159
|
|
140
160
|
test "standard form for existing entry" do
|
@@ -155,7 +175,6 @@ class StandardHelperTest < ActionView::TestCase
|
|
155
175
|
assert_match /input .*?type="submit" .*?value="Save"/, f
|
156
176
|
end
|
157
177
|
|
158
|
-
|
159
178
|
test "standard form for new entry" do
|
160
179
|
e = CrudTestModel.new
|
161
180
|
f = with_test_routing do
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
7
|
+
<title><%= @title %></title>
|
8
|
+
<%= stylesheet_link_tag 'crud' %>
|
9
|
+
<%= javascript_include_tag :all %>
|
10
|
+
<%= csrf_meta_tag %>
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
|
14
|
+
<ul id="menu">
|
15
|
+
<li><%= link_to 'People', people_path %></li>
|
16
|
+
<li><%= link_to 'Cities', cities_path %></li>
|
17
|
+
</ul>
|
18
|
+
|
19
|
+
<h1><%= @title %></h1>
|
20
|
+
|
21
|
+
<p id="flash_notice"><%= flash[:notice] %></p>
|
22
|
+
|
23
|
+
<%= yield %>
|
24
|
+
|
25
|
+
</body>
|
26
|
+
</html>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry_crud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Pascal Zumkehr
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-09-24 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -56,6 +56,7 @@ files:
|
|
56
56
|
- lib/generators/dry_crud/templates/app/views/crud/_attrs.html.erb
|
57
57
|
- lib/generators/dry_crud/templates/app/views/crud/_form.html.erb
|
58
58
|
- lib/generators/dry_crud/templates/app/views/crud/_list.html.erb
|
59
|
+
- lib/generators/dry_crud/templates/app/views/crud/_search.html.erb
|
59
60
|
- lib/generators/dry_crud/templates/app/views/crud/edit.html.erb
|
60
61
|
- lib/generators/dry_crud/templates/app/views/crud/index.html.erb
|
61
62
|
- lib/generators/dry_crud/templates/app/views/crud/new.html.erb
|
@@ -66,13 +67,15 @@ files:
|
|
66
67
|
- lib/generators/dry_crud/templates/INSTALL
|
67
68
|
- lib/generators/dry_crud/templates/public/stylesheets/crud.css
|
68
69
|
- lib/generators/dry_crud/templates/test/crud_test_model.rb
|
70
|
+
- lib/generators/dry_crud/templates/test/custom_assertions.rb
|
69
71
|
- lib/generators/dry_crud/templates/test/functional/crud_controller_test_helper.rb
|
70
72
|
- lib/generators/dry_crud/templates/test/functional/crud_test_models_controller_test.rb
|
71
|
-
- lib/generators/dry_crud/templates/test/unit/
|
72
|
-
- lib/generators/dry_crud/templates/test/unit/
|
73
|
-
- lib/generators/dry_crud/templates/test/unit/
|
74
|
-
- lib/generators/dry_crud/templates/test/unit/
|
75
|
-
- lib/generators/dry_crud/templates/test/unit/
|
73
|
+
- lib/generators/dry_crud/templates/test/unit/custom_assertions_test.rb
|
74
|
+
- lib/generators/dry_crud/templates/test/unit/helpers/crud_helper_test.rb
|
75
|
+
- lib/generators/dry_crud/templates/test/unit/helpers/render_inheritable_test.rb
|
76
|
+
- lib/generators/dry_crud/templates/test/unit/helpers/standard_form_builder_test.rb
|
77
|
+
- lib/generators/dry_crud/templates/test/unit/helpers/standard_helper_test.rb
|
78
|
+
- lib/generators/dry_crud/templates/test/unit/helpers/standard_table_builder_test.rb
|
76
79
|
- lib/generators/dry_crud/USAGE
|
77
80
|
- test/templates/app/controllers/ajax_controller.rb
|
78
81
|
- test/templates/app/controllers/application_controller.rb
|
@@ -84,10 +87,11 @@ files:
|
|
84
87
|
- test/templates/app/views/ajax/_hello.html.erb
|
85
88
|
- test/templates/app/views/ajax/ajax.js.rjs
|
86
89
|
- test/templates/app/views/ajax/index.html.erb
|
87
|
-
- test/templates/app/views/cities/_attrs.html.erb
|
88
90
|
- test/templates/app/views/cities/_form.html.erb
|
89
91
|
- test/templates/app/views/cities/_hello.html.erb
|
90
92
|
- test/templates/app/views/cities/_list.html.erb
|
93
|
+
- test/templates/app/views/layouts/crud.html.erb
|
94
|
+
- test/templates/app/views/people/_attrs.html.erb
|
91
95
|
- test/templates/config/routes.rb
|
92
96
|
- test/templates/db/migrate/20100511174904_create_people_and_cities.rb
|
93
97
|
- test/templates/test/fixtures/cities.yml
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= render_attrs @entry, default_attrs %>
|