dry_crud 1.7.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +126 -87
- data/VERSION +1 -1
- data/lib/generators/dry_crud/dry_crud_generator.rb +42 -22
- data/lib/generators/dry_crud/templates/INSTALL +5 -5
- data/lib/generators/dry_crud/templates/app/assets/stylesheets/crud.scss +0 -20
- data/lib/generators/dry_crud/templates/app/assets/stylesheets/sample.scss +24 -4
- data/lib/generators/dry_crud/templates/app/controllers/crud/generic_model.rb +89 -0
- data/lib/generators/dry_crud/templates/app/controllers/crud/nestable.rb +70 -0
- data/lib/generators/dry_crud/templates/app/controllers/crud/rememberable.rb +64 -0
- data/lib/generators/dry_crud/templates/app/controllers/crud/render_callbacks.rb +46 -0
- data/lib/generators/dry_crud/templates/app/controllers/crud/responder.rb +31 -0
- data/lib/generators/dry_crud/templates/app/controllers/crud/searchable.rb +55 -0
- data/lib/generators/dry_crud/templates/app/controllers/crud/sortable.rb +63 -0
- data/lib/generators/dry_crud/templates/app/controllers/crud_controller.rb +66 -69
- data/lib/generators/dry_crud/templates/app/controllers/list_controller.rb +23 -326
- data/lib/generators/dry_crud/templates/app/helpers/actions_helper.rb +64 -0
- data/lib/generators/dry_crud/templates/app/helpers/crud/form_builder.rb +331 -0
- data/lib/generators/dry_crud/templates/app/helpers/crud/table_builder.rb +280 -0
- data/lib/generators/dry_crud/templates/app/helpers/form_helper.rb +52 -0
- data/lib/generators/dry_crud/templates/app/helpers/format_helper.rb +164 -0
- data/lib/generators/dry_crud/templates/app/helpers/i18n_helper.rb +85 -0
- data/lib/generators/dry_crud/templates/app/helpers/table_helper.rb +83 -0
- data/lib/generators/dry_crud/templates/app/helpers/utility_helper.rb +84 -0
- data/lib/generators/dry_crud/templates/app/views/crud/_actions_edit.html.erb +3 -3
- data/lib/generators/dry_crud/templates/app/views/crud/_actions_edit.html.haml +3 -3
- data/lib/generators/dry_crud/templates/app/views/crud/_actions_index.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/_actions_index.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/_actions_show.html.erb +3 -3
- data/lib/generators/dry_crud/templates/app/views/crud/_actions_show.html.haml +3 -3
- data/lib/generators/dry_crud/templates/app/views/crud/_attrs.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/_attrs.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/_form.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/_form.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/edit.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/edit.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/new.html.erb +2 -2
- data/lib/generators/dry_crud/templates/app/views/crud/new.html.haml +2 -2
- data/lib/generators/dry_crud/templates/app/views/crud/show.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/crud/show.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/layouts/_flash.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/layouts/_nav.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/layouts/_nav.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/layouts/crud.html.erb +15 -7
- data/lib/generators/dry_crud/templates/app/views/layouts/crud.html.haml +18 -8
- data/lib/generators/dry_crud/templates/app/views/list/_search.html.erb +3 -3
- data/lib/generators/dry_crud/templates/app/views/list/_search.html.haml +3 -3
- data/lib/generators/dry_crud/templates/app/views/list/index.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/list/index.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/shared/_error_messages.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/shared/_error_messages.html.haml +1 -1
- data/lib/generators/dry_crud/templates/app/views/shared/_labeled.html.erb +2 -4
- data/lib/generators/dry_crud/templates/app/views/shared/_labeled.html.haml +2 -3
- data/lib/generators/dry_crud/templates/config/initializers/field_error_proc.rb +5 -1
- data/lib/generators/dry_crud/templates/config/locales/crud.de.yml +64 -0
- data/lib/generators/dry_crud/templates/config/locales/{en_crud.yml → crud.en.yml} +2 -2
- data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +241 -231
- data/lib/generators/dry_crud/templates/spec/helpers/crud/form_builder_spec.rb +226 -0
- data/lib/generators/dry_crud/templates/spec/helpers/{standard_table_builder_spec.rb → crud/table_builder_spec.rb} +36 -34
- data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +238 -0
- data/lib/generators/dry_crud/templates/spec/helpers/format_helper_spec.rb +244 -0
- data/lib/generators/dry_crud/templates/spec/helpers/i18n_helper_spec.rb +132 -0
- data/lib/generators/dry_crud/templates/spec/helpers/table_helper_spec.rb +265 -0
- data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +74 -0
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +185 -100
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +58 -49
- data/lib/generators/dry_crud/templates/test/{functional → controllers}/crud_test_models_controller_test.rb +112 -91
- data/lib/generators/dry_crud/templates/test/{unit/helpers/standard_form_builder_test.rb → helpers/crud/form_builder_test.rb} +79 -62
- data/lib/generators/dry_crud/templates/test/{unit/helpers/standard_table_builder_test.rb → helpers/crud/table_builder_test.rb} +31 -28
- data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +85 -0
- data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +129 -0
- data/lib/generators/dry_crud/templates/test/helpers/format_helper_test.rb +163 -0
- data/lib/generators/dry_crud/templates/test/helpers/i18n_helper_test.rb +79 -0
- data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +217 -0
- data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +63 -0
- data/lib/generators/dry_crud/templates/test/{functional → support}/crud_controller_test_helper.rb +70 -59
- data/lib/generators/dry_crud/templates/test/{crud_test_model.rb → support/crud_test_model.rb} +107 -75
- data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +83 -0
- metadata +83 -146
- data/Rakefile +0 -211
- data/lib/generators/dry_crud/templates/app/helpers/crud_helper.rb +0 -168
- data/lib/generators/dry_crud/templates/app/helpers/list_helper.rb +0 -27
- data/lib/generators/dry_crud/templates/app/helpers/standard_form_builder.rb +0 -261
- data/lib/generators/dry_crud/templates/app/helpers/standard_helper.rb +0 -304
- data/lib/generators/dry_crud/templates/app/helpers/standard_table_builder.rb +0 -178
- data/lib/generators/dry_crud/templates/spec/helpers/crud_helper_spec.rb +0 -146
- data/lib/generators/dry_crud/templates/spec/helpers/list_helper_spec.rb +0 -154
- data/lib/generators/dry_crud/templates/spec/helpers/standard_form_builder_spec.rb +0 -215
- data/lib/generators/dry_crud/templates/spec/helpers/standard_helper_spec.rb +0 -387
- data/lib/generators/dry_crud/templates/test/custom_assertions.rb +0 -78
- data/lib/generators/dry_crud/templates/test/unit/custom_assertions_test.rb +0 -117
- data/lib/generators/dry_crud/templates/test/unit/helpers/crud_helper_test.rb +0 -111
- data/lib/generators/dry_crud/templates/test/unit/helpers/list_helper_test.rb +0 -123
- data/lib/generators/dry_crud/templates/test/unit/helpers/standard_helper_test.rb +0 -281
- data/test/templates/Gemfile +0 -46
- data/test/templates/app/controllers/admin/cities_controller.rb +0 -7
- data/test/templates/app/controllers/admin/countries_controller.rb +0 -13
- data/test/templates/app/controllers/ajax_controller.rb +0 -9
- data/test/templates/app/controllers/people_controller.rb +0 -13
- data/test/templates/app/controllers/vips_controller.rb +0 -19
- data/test/templates/app/helpers/cities_helper.rb +0 -9
- data/test/templates/app/helpers/people_helper.rb +0 -8
- data/test/templates/app/models/city.rb +0 -28
- data/test/templates/app/models/country.rb +0 -16
- data/test/templates/app/models/person.rb +0 -12
- data/test/templates/app/views/admin/cities/_actions_index.html.erb +0 -2
- data/test/templates/app/views/admin/cities/_actions_index.html.haml +0 -2
- data/test/templates/app/views/admin/cities/_attrs.html.erb +0 -1
- data/test/templates/app/views/admin/cities/_attrs.html.haml +0 -1
- data/test/templates/app/views/admin/cities/_form.html.erb +0 -7
- data/test/templates/app/views/admin/cities/_form.html.haml +0 -5
- data/test/templates/app/views/admin/cities/_hello.html.erb +0 -1
- data/test/templates/app/views/admin/cities/_hello.html.haml +0 -1
- data/test/templates/app/views/admin/cities/_list.html.erb +0 -3
- data/test/templates/app/views/admin/cities/_list.html.haml +0 -3
- data/test/templates/app/views/admin/countries/_list.html.erb +0 -4
- data/test/templates/app/views/admin/countries/_list.html.haml +0 -3
- data/test/templates/app/views/ajax/_actions_index.html.erb +0 -8
- data/test/templates/app/views/ajax/_actions_index.html.haml +0 -8
- data/test/templates/app/views/ajax/_actions_show.html.erb +0 -4
- data/test/templates/app/views/ajax/_actions_show.html.haml +0 -4
- data/test/templates/app/views/ajax/_form.html.erb +0 -2
- data/test/templates/app/views/ajax/_form.html.haml +0 -2
- data/test/templates/app/views/ajax/_hello.html.erb +0 -1
- data/test/templates/app/views/ajax/_hello.html.haml +0 -1
- data/test/templates/app/views/ajax/ajax.js.erb +0 -1
- data/test/templates/app/views/ajax/ajax.js.haml +0 -1
- data/test/templates/app/views/ajax/edit.js.erb +0 -1
- data/test/templates/app/views/ajax/edit.js.haml +0 -1
- data/test/templates/app/views/ajax/show.js.erb +0 -1
- data/test/templates/app/views/ajax/show.js.haml +0 -1
- data/test/templates/app/views/ajax/update.js.erb +0 -5
- data/test/templates/app/views/ajax/update.js.haml +0 -5
- data/test/templates/app/views/layouts/_nav.html.erb +0 -6
- data/test/templates/app/views/layouts/_nav.html.haml +0 -5
- data/test/templates/app/views/layouts/bootstrap.html.erb +0 -68
- data/test/templates/app/views/layouts/bootstrap.html.haml +0 -49
- data/test/templates/app/views/people/_attrs.html.erb +0 -5
- data/test/templates/app/views/people/_attrs.html.haml +0 -4
- data/test/templates/app/views/people/_list.html.erb +0 -1
- data/test/templates/app/views/people/_list.html.haml +0 -1
- data/test/templates/config/database.yml +0 -21
- data/test/templates/config/locales/en_cities.yml +0 -56
- data/test/templates/config/routes.rb +0 -32
- data/test/templates/db/migrate/20100511174904_create_people_and_cities.rb +0 -26
- data/test/templates/db/seeds.rb +0 -74
- data/test/templates/spec/controllers/admin/cities_controller_spec.rb +0 -74
- data/test/templates/spec/controllers/admin/countries_controller_spec.rb +0 -56
- data/test/templates/spec/controllers/people_controller_spec.rb +0 -80
- data/test/templates/spec/routing/cities_routing_spec.rb +0 -11
- data/test/templates/spec/routing/countries_routing_spec.rb +0 -11
- data/test/templates/test/fixtures/cities.yml +0 -11
- data/test/templates/test/fixtures/countries.yml +0 -11
- data/test/templates/test/fixtures/people.yml +0 -14
- data/test/templates/test/functional/admin/cities_controller_test.rb +0 -59
- data/test/templates/test/functional/admin/countries_controller_test.rb +0 -42
- data/test/templates/test/functional/people_controller_test.rb +0 -68
@@ -1,11 +1,11 @@
|
|
1
1
|
|
2
|
-
Thank you for using dry_crud. Feel free to adapt all generated classes to
|
3
|
-
your needs. To integrate dry_crud into your code, only a few additions are
|
2
|
+
Thank you for using dry_crud. Feel free to adapt all generated classes to
|
3
|
+
your needs. To integrate dry_crud into your code, only a few additions are
|
4
4
|
required:
|
5
5
|
|
6
|
-
* For uniform CRUD functionallity, just subclass your controllers from
|
7
|
-
CrudController.
|
8
|
-
* Overwrite the
|
6
|
+
* For uniform CRUD functionallity, just subclass your controllers from
|
7
|
+
CrudController.
|
8
|
+
* Overwrite the #to_s method of your models for a human-friendly
|
9
9
|
representation.
|
10
10
|
|
11
11
|
|
@@ -7,26 +7,6 @@
|
|
7
7
|
text-align: center;
|
8
8
|
}
|
9
9
|
|
10
|
-
.labeled {
|
11
|
-
vertical-align: top;
|
12
|
-
padding: 2px 0 2px;
|
13
|
-
clear: both;
|
14
|
-
}
|
15
|
-
|
16
|
-
.labeled label {
|
17
|
-
width: 120px;
|
18
|
-
padding-right: 5px;
|
19
|
-
float: left;
|
20
|
-
}
|
21
|
-
|
22
|
-
.labeled .value {
|
23
|
-
margin-left: 130px;
|
24
|
-
}
|
25
|
-
|
26
|
-
.labeled .value p {
|
27
|
-
margin: 0;
|
28
|
-
}
|
29
|
-
|
30
10
|
#content {
|
31
11
|
clear: both;
|
32
12
|
padding-top: 5px;
|
@@ -38,7 +38,7 @@ h1 {
|
|
38
38
|
background-color: #F8F8F8;
|
39
39
|
}
|
40
40
|
|
41
|
-
.table tr:nth-child(even) {
|
41
|
+
.table tr:nth-child(even) {
|
42
42
|
background-color: #F0F0F0;
|
43
43
|
}
|
44
44
|
|
@@ -67,6 +67,27 @@ a img {
|
|
67
67
|
border: none;
|
68
68
|
}
|
69
69
|
|
70
|
+
dl {
|
71
|
+
vertical-align: top;
|
72
|
+
padding: 2px 0 2px;
|
73
|
+
clear: both;
|
74
|
+
}
|
75
|
+
|
76
|
+
dt {
|
77
|
+
width: 120px;
|
78
|
+
padding-right: 5px;
|
79
|
+
float: left;
|
80
|
+
font-style: italic;
|
81
|
+
}
|
82
|
+
|
83
|
+
dd {
|
84
|
+
margin-left: 130px;
|
85
|
+
}
|
86
|
+
|
87
|
+
dd p {
|
88
|
+
margin: 0;
|
89
|
+
}
|
90
|
+
|
70
91
|
.table {
|
71
92
|
margin-top: 10px;
|
72
93
|
}
|
@@ -81,7 +102,6 @@ table.table {
|
|
81
102
|
div.table {}
|
82
103
|
|
83
104
|
table.table th {
|
84
|
-
text-align: left;
|
85
105
|
background-color: $theme_color;
|
86
106
|
color: white;
|
87
107
|
font-weight: bold;
|
@@ -89,12 +109,12 @@ table.table th {
|
|
89
109
|
}
|
90
110
|
|
91
111
|
table.table th a {
|
92
|
-
color: white;
|
112
|
+
color: white;
|
93
113
|
text-decoration: none;
|
94
114
|
}
|
95
115
|
|
96
116
|
table.table td {
|
97
|
-
padding: 2px 4px;
|
117
|
+
padding: 2px 4px;
|
98
118
|
}
|
99
119
|
|
100
120
|
label {
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Crud
|
4
|
+
# Connects the including controller to the model whose name corrsponds to
|
5
|
+
# the controller's name.
|
6
|
+
#
|
7
|
+
# The two main methods are +model_class+ and +model_scope+.
|
8
|
+
# Additional helper methods store and retrieve values in instance variables
|
9
|
+
# named after their class.
|
10
|
+
module GenericModel
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
included do
|
14
|
+
helper_method :model_class, :models_label, :path_args
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
delegate :model_class, :models_label, :model_identifier, to: 'self.class'
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# The scope where model entries will be listed and created.
|
24
|
+
# This is mainly used for nested models to provide the
|
25
|
+
# required context.
|
26
|
+
def model_scope
|
27
|
+
<% if Rails.version < '4.0' -%>
|
28
|
+
model_class.scoped
|
29
|
+
<% else -%>
|
30
|
+
model_class.all
|
31
|
+
<% end -%><%# > fixing rdoc -%>
|
32
|
+
end
|
33
|
+
|
34
|
+
# The path arguments to link to the given model entry.
|
35
|
+
# If the controller is nested, this provides the required context.
|
36
|
+
def path_args(last)
|
37
|
+
last
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get the instance variable named after the +model_class+.
|
41
|
+
# If the collection variable is required, pass true as the second argument.
|
42
|
+
def get_model_ivar(plural = false)
|
43
|
+
name = ivar_name(model_class)
|
44
|
+
name = name.pluralize if plural
|
45
|
+
instance_variable_get(:"@#{name}")
|
46
|
+
end
|
47
|
+
|
48
|
+
# Sets an instance variable with the underscored class name if the given
|
49
|
+
# value. If the value is a collection, sets the plural name.
|
50
|
+
def set_model_ivar(value)
|
51
|
+
name = if value.respond_to?(:klass) # ActiveRecord::Relation
|
52
|
+
ivar_name(value.klass).pluralize
|
53
|
+
elsif value.respond_to?(:each) # Array
|
54
|
+
ivar_name(value.first.class).pluralize
|
55
|
+
else
|
56
|
+
ivar_name(value.class)
|
57
|
+
end
|
58
|
+
instance_variable_set(:"@#{name}", value)
|
59
|
+
end
|
60
|
+
|
61
|
+
def ivar_name(klass)
|
62
|
+
klass.model_name.param_key
|
63
|
+
end
|
64
|
+
|
65
|
+
# Class methods from GenericModel.
|
66
|
+
module ClassMethods
|
67
|
+
# The ActiveRecord class of the model.
|
68
|
+
def model_class
|
69
|
+
@model_class ||= controller_name.classify.constantize
|
70
|
+
end
|
71
|
+
|
72
|
+
# The identifier of the model used for form parameters.
|
73
|
+
# I.e., the symbol of the underscored model name.
|
74
|
+
def model_identifier
|
75
|
+
@model_identifier ||= model_class.model_name.param_key
|
76
|
+
end
|
77
|
+
|
78
|
+
# A human readable plural name of the model.
|
79
|
+
def models_label(plural = true)
|
80
|
+
opts = { count: (plural ? 3 : 1) }
|
81
|
+
opts[:default] = model_class.model_name.human.titleize
|
82
|
+
opts[:default] = opts[:default].pluralize if plural
|
83
|
+
|
84
|
+
model_class.model_name.human(opts)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Crud
|
4
|
+
# Provides functionality to nest controllers/resources.
|
5
|
+
# If a controller is nested, the parent classes and namespaces
|
6
|
+
# may be defined as an array in the +nesting+ class attribute.
|
7
|
+
#
|
8
|
+
# For example, a cities controller, nested in country and a admin
|
9
|
+
# namespace, may define this attribute as follows:
|
10
|
+
# self.nesting = :admin, Country
|
11
|
+
module Nestable
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
# Adds the :nesting class attribute and parent helper methods
|
15
|
+
# to the including controller.
|
16
|
+
included do
|
17
|
+
class_attribute :nesting
|
18
|
+
|
19
|
+
helper_method :parent, :parents
|
20
|
+
|
21
|
+
alias_method_chain :path_args, :nesting
|
22
|
+
alias_method_chain :model_scope, :nesting
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Returns the direct parent ActiveRecord of the current request, if any.
|
28
|
+
def parent
|
29
|
+
parents.select { |p| p.is_a?(ActiveRecord::Base) }.last
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the parent entries of the current request, if any.
|
33
|
+
# These are ActiveRecords or namespace symbols, corresponding
|
34
|
+
# to the defined nesting attribute.
|
35
|
+
def parents
|
36
|
+
@parents ||= Array(nesting).map do |p|
|
37
|
+
if p.is_a?(Class) && p < ActiveRecord::Base
|
38
|
+
parent_entry(p)
|
39
|
+
else
|
40
|
+
p
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Loads the parent entry for the given ActiveRecord class.
|
46
|
+
# By default, performs a find with the class_name_id param.
|
47
|
+
def parent_entry(clazz)
|
48
|
+
set_model_ivar(clazz.find(params["#{clazz.name.underscore}_id"]))
|
49
|
+
end
|
50
|
+
|
51
|
+
# An array of objects used in url_for and related functions.
|
52
|
+
def path_args_with_nesting(last)
|
53
|
+
parents + [last]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Uses the parent entry (if any) to constrain the model scope.
|
57
|
+
def model_scope_with_nesting
|
58
|
+
if parent.present?
|
59
|
+
parent_scope
|
60
|
+
else
|
61
|
+
model_scope_without_nesting
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# The model scope for the current parent resource.
|
66
|
+
def parent_scope
|
67
|
+
parent.send(model_class.name.underscore.pluralize)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Crud
|
4
|
+
# Remembers certain params of the index action in order to return
|
5
|
+
# to the same list after an entry was viewed or edited.
|
6
|
+
# If the index is called with a param :returning, the remembered params
|
7
|
+
# will be re-used to present the user the same list as she left it.
|
8
|
+
#
|
9
|
+
# Define a list of param keys that should be remembered for the list action
|
10
|
+
# with the class attribute +remember_params+.
|
11
|
+
#
|
12
|
+
# The params are stored separately for each different +remember_key+, which
|
13
|
+
# defaults to the current request's path.
|
14
|
+
module Rememberable
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
|
17
|
+
included do
|
18
|
+
class_attribute :remember_params
|
19
|
+
self.remember_params = [:q, :sort, :sort_dir, :page]
|
20
|
+
|
21
|
+
before_filter :handle_remember_params, only: [:index]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Store and restore the corresponding params.
|
27
|
+
def handle_remember_params
|
28
|
+
remembered = remembered_params
|
29
|
+
|
30
|
+
restore_params_on_return(remembered)
|
31
|
+
store_current_params(remembered)
|
32
|
+
clear_void_params(remembered)
|
33
|
+
end
|
34
|
+
|
35
|
+
def restore_params_on_return(remembered)
|
36
|
+
if params[:returning]
|
37
|
+
remember_params.each { |p| params[p] ||= remembered[p] }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def store_current_params(remembered)
|
42
|
+
remember_params.each do |p|
|
43
|
+
remembered[p] = params[p].presence
|
44
|
+
remembered.delete(p) if remembered[p].nil?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear_void_params(remembered)
|
49
|
+
session[:list_params].delete(remember_key) if remembered.blank?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get the params stored in the session.
|
53
|
+
def remembered_params
|
54
|
+
session[:list_params] ||= {}
|
55
|
+
session[:list_params][remember_key] ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
# Params are stored by request path to play nice when a controller
|
59
|
+
# is used in different routes.
|
60
|
+
def remember_key
|
61
|
+
request.path
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Crud
|
4
|
+
# Provide +before_render+ callbacks.
|
5
|
+
module RenderCallbacks
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
extend ActiveModel::Callbacks
|
10
|
+
|
11
|
+
alias_method_chain :render, :callbacks
|
12
|
+
end
|
13
|
+
|
14
|
+
# Helper method to run +before_render+ callbacks and render the action.
|
15
|
+
# If a callback renders or redirects, the action is not rendered.
|
16
|
+
def render_with_callbacks(*args, &block)
|
17
|
+
options = _normalize_render(*args, &block)
|
18
|
+
callback = "render_#{options[:template]}"
|
19
|
+
|
20
|
+
run_callbacks(callback) if respond_to?(:"_#{callback}_callbacks", true)
|
21
|
+
|
22
|
+
render_without_callbacks(*args, &block) unless performed?
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Helper method the run the given block in between the before and after
|
28
|
+
# callbacks of the given kinds.
|
29
|
+
def with_callbacks(*kinds, &block)
|
30
|
+
kinds.reverse.reduce(block) do |a, e|
|
31
|
+
-> { run_callbacks(e, &a) }
|
32
|
+
end.call
|
33
|
+
end
|
34
|
+
|
35
|
+
# Class methods for callbacks.
|
36
|
+
module ClassMethods
|
37
|
+
# Defines before callbacks for the render actions.
|
38
|
+
def define_render_callbacks(*actions)
|
39
|
+
args = actions.map { |a| :"render_#{a}" }
|
40
|
+
args << { only: :before,
|
41
|
+
terminator: 'result == false || performed?' }
|
42
|
+
define_model_callbacks(*args)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Crud
|
4
|
+
# Custom Responder that handles the controller's +path_args+.
|
5
|
+
# An additional :success option is used to handle action callback
|
6
|
+
# chain halts.
|
7
|
+
class Responder < ActionController::Responder
|
8
|
+
|
9
|
+
def initialize(controller, resources, options = {})
|
10
|
+
super(controller, with_path_args(resources, controller), options)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Check whether the resource has errors. Additionally checks the :success
|
16
|
+
# option.
|
17
|
+
def has_errors?
|
18
|
+
options[:success] == false || super
|
19
|
+
end
|
20
|
+
|
21
|
+
# Wraps the resources with the path_args for correct nesting.
|
22
|
+
def with_path_args(resources, controller)
|
23
|
+
if resources.size == 1
|
24
|
+
Array(controller.send(:path_args, resources.first))
|
25
|
+
else
|
26
|
+
resources
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Crud
|
4
|
+
# The search functionality for the index table.
|
5
|
+
# Define an array of searchable columns in your subclassing controllers
|
6
|
+
# using the class attribute +search_columns+.
|
7
|
+
module Searchable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
class_attribute :search_columns
|
12
|
+
self.search_columns = []
|
13
|
+
|
14
|
+
helper_method :search_support?
|
15
|
+
|
16
|
+
alias_method_chain :list_entries, :search
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Enhance the list entries with an optional search criteria
|
22
|
+
def list_entries_with_search
|
23
|
+
list_entries_without_search.where(search_condition)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Compose the search condition with a basic SQL OR query.
|
27
|
+
def search_condition
|
28
|
+
if search_support? && params[:q].present?
|
29
|
+
col_clause = search_column_clause
|
30
|
+
terms = params[:q].split(/\s+/).map { |t| "%#{t}%" }
|
31
|
+
term_clause = terms.map { |t| "(#{col_clause})" }.join(' AND ')
|
32
|
+
|
33
|
+
term_params = terms.map { |t| [t] * search_columns.size }.flatten
|
34
|
+
["(#{term_clause})", *term_params]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# SQL where clause with all search colums or'ed.
|
39
|
+
def search_column_clause
|
40
|
+
search_columns.map do |f|
|
41
|
+
if f.to_s.include?('.')
|
42
|
+
"#{f} LIKE ?"
|
43
|
+
else
|
44
|
+
"#{model_class.table_name}.#{f} LIKE ?"
|
45
|
+
end
|
46
|
+
end.join(' OR ')
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns true if this controller has searchable columns.
|
50
|
+
def search_support?
|
51
|
+
search_columns.present?
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|