dry_crud 3.0.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/app/controllers/crud_controller.rb +10 -8
- data/app/controllers/dry_crud/generic_model.rb +6 -4
- data/app/controllers/dry_crud/nestable.rb +9 -11
- data/app/controllers/dry_crud/rememberable.rb +5 -1
- data/app/controllers/dry_crud/render_callbacks.rb +40 -19
- data/app/controllers/dry_crud/searchable.rb +40 -31
- data/app/controllers/dry_crud/sortable.rb +36 -26
- data/app/controllers/list_controller.rb +2 -2
- data/app/helpers/dry_crud/form/builder.rb +21 -13
- data/app/helpers/dry_crud/form/control.rb +8 -9
- data/app/helpers/dry_crud/table/actions.rb +6 -1
- data/app/helpers/dry_crud/table/builder.rb +4 -2
- data/app/helpers/dry_crud/table/col.rb +12 -1
- data/app/helpers/dry_crud/table/sorting.rb +7 -1
- data/app/helpers/form_helper.rb +7 -7
- data/app/helpers/format_helper.rb +3 -3
- data/app/helpers/i18n_helper.rb +3 -3
- data/app/helpers/utility_helper.rb +4 -1
- data/lib/dry_crud.rb +1 -2
- data/lib/dry_crud/engine.rb +5 -7
- data/lib/generators/dry_crud/dry_crud_generator.rb +3 -4
- data/lib/generators/dry_crud/dry_crud_generator_base.rb +6 -8
- data/lib/generators/dry_crud/file_generator.rb +1 -3
- data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +8 -18
- data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +1 -1
- data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +4 -4
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +7 -17
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +13 -29
- data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +25 -44
- data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +0 -1
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +3 -4
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/table/builder_test.rb +0 -2
- data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +2 -1
- data/lib/generators/dry_crud/templates/test/helpers/format_helper_test.rb +1 -1
- data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +8 -17
- data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +3 -0
- data/lib/generators/dry_crud/templates/test/support/crud_controller_test_helper.rb +27 -30
- data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +11 -13
- data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +7 -3
- data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +5 -9
- data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +1 -1
- metadata +10 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd475eb483f54acdff9dff23ae75d80715edfcdb
|
4
|
+
data.tar.gz: 7ba54fb2d5a22f562627fd0641f23e2a32a975ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38e784965cdb8dc622b659437fa6cb2e4be27eb3eb17b3c1686a5ec6cdfded184fb08fb10a533ff6d7f9e14331045b111aadbde8a371d6c59272462c589839e6
|
7
|
+
data.tar.gz: e0b78f3534243dd715cb53c6ddbfc547f236e90e84ee6a7439e392a4d0b837f17fd2a7e9e5a24fb1b885611aaf44f7c2dca47ac388256279559cd5b212e24699
|
data/README.rdoc
CHANGED
@@ -33,7 +33,7 @@ To integrate dry_crud into your code, only a few additions are required:
|
|
33
33
|
* Optionally define a +list+ scope in your models to be used in the +index+ action.
|
34
34
|
* Optionally define a +options_list+ scope in your models to be used in select dropdowns.
|
35
35
|
|
36
|
-
From version
|
36
|
+
From version 5.0 onwards, the major and minor version numbers will be kept in sync with Rails, and only the matching Rails version is supported. Version 3.0 is compatible 4.2, Version 2.0 and higher are compatible with Rails 4 and Rails 3.2. dry_crud is tested with Ruby 2.2.5 and JRuby. If you are using Ruby 1.9.3, please refer to version 3.0.0.
|
37
37
|
|
38
38
|
|
39
39
|
== Background
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
5.0.0
|
@@ -22,8 +22,6 @@ class CrudController < ListController
|
|
22
22
|
# further down.
|
23
23
|
define_render_callbacks :show, :new, :edit
|
24
24
|
|
25
|
-
hide_action :run_callbacks
|
26
|
-
|
27
25
|
before_action :entry, only: [:show, :new, :edit, :update, :destroy]
|
28
26
|
|
29
27
|
helper_method :entry, :full_entry_label
|
@@ -57,12 +55,12 @@ class CrudController < ListController
|
|
57
55
|
# in the given block will take precedence over the one defined here.
|
58
56
|
#
|
59
57
|
# Specify a :location option if you wish to do a custom redirect.
|
60
|
-
def create(options = {}, &
|
58
|
+
def create(options = {}, &_block)
|
61
59
|
assign_attributes
|
62
60
|
created = with_callbacks(:create, :save) { entry.save }
|
63
61
|
|
64
62
|
respond_to do |format|
|
65
|
-
|
63
|
+
yield(format, created) if block_given?
|
66
64
|
if created
|
67
65
|
format.html { redirect_on_success(options) }
|
68
66
|
format.json { render :show, status: :created, location: show_path }
|
@@ -91,12 +89,12 @@ class CrudController < ListController
|
|
91
89
|
# in the given block will take precedence over the one defined here.
|
92
90
|
#
|
93
91
|
# Specify a :location option if you wish to do a custom redirect.
|
94
|
-
def update(options = {}, &
|
92
|
+
def update(options = {}, &_block)
|
95
93
|
assign_attributes
|
96
94
|
updated = with_callbacks(:update, :save) { entry.save }
|
97
95
|
|
98
96
|
respond_to do |format|
|
99
|
-
|
97
|
+
yield(format, updated) if block_given?
|
100
98
|
if updated
|
101
99
|
format.html { redirect_on_success(options) }
|
102
100
|
format.json { render :show, status: :ok, location: show_path }
|
@@ -119,11 +117,11 @@ class CrudController < ListController
|
|
119
117
|
# in the given block will take precedence over the one defined here.
|
120
118
|
#
|
121
119
|
# Specify a :location option if you wish to do a custom redirect.
|
122
|
-
def destroy(options = {}, &
|
120
|
+
def destroy(options = {}, &_block)
|
123
121
|
destroyed = run_callbacks(:destroy) { entry.destroy }
|
124
122
|
|
125
123
|
respond_to do |format|
|
126
|
-
|
124
|
+
yield(format, destroyed) if block_given?
|
127
125
|
if destroyed
|
128
126
|
format.html { redirect_on_success(options) }
|
129
127
|
format.json { head :no_content }
|
@@ -204,13 +202,17 @@ class CrudController < ListController
|
|
204
202
|
|
205
203
|
# A label for the current entry, including the model name.
|
206
204
|
def full_entry_label
|
205
|
+
# rubocop:disable Rails/OutputSafety
|
207
206
|
"#{models_label(false)} <i>#{ERB::Util.h(entry)}</i>".html_safe
|
207
|
+
# rubocop:enable Rails/OutputSafety
|
208
208
|
end
|
209
209
|
|
210
210
|
# Html safe error messages of the current entry.
|
211
211
|
def error_messages
|
212
|
+
# rubocop:disable Rails/OutputSafety
|
212
213
|
escaped = entry.errors.full_messages.map { |m| ERB::Util.html_escape(m) }
|
213
214
|
escaped.join('<br/>').html_safe
|
215
|
+
# rubocop:enable Rails/OutputSafety
|
214
216
|
end
|
215
217
|
|
216
218
|
# Class methods for CrudActions.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
module DryCrud
|
4
|
+
|
4
5
|
# Connects the including controller to the model whose name corrsponds to
|
5
6
|
# the controller's name.
|
6
7
|
#
|
@@ -8,6 +9,7 @@ module DryCrud
|
|
8
9
|
# Additional helper methods store and retrieve values in instance variables
|
9
10
|
# named after their class.
|
10
11
|
module GenericModel
|
12
|
+
|
11
13
|
extend ActiveSupport::Concern
|
12
14
|
|
13
15
|
included do
|
@@ -18,8 +20,6 @@ module DryCrud
|
|
18
20
|
delegate :model_class, :models_label, :model_identifier, to: 'self.class'
|
19
21
|
end
|
20
22
|
|
21
|
-
private
|
22
|
-
|
23
23
|
# The scope where model entries will be listed and created.
|
24
24
|
# This is mainly used for nested models to provide the
|
25
25
|
# required context.
|
@@ -38,7 +38,8 @@ module DryCrud
|
|
38
38
|
def model_ivar_get(plural = false)
|
39
39
|
name = ivar_name(model_class)
|
40
40
|
name = name.pluralize if plural
|
41
|
-
|
41
|
+
name = :"@#{name}"
|
42
|
+
instance_variable_get(name) if instance_variable_defined?(name)
|
42
43
|
end
|
43
44
|
|
44
45
|
# Sets an instance variable with the underscored class name if the given
|
@@ -60,6 +61,7 @@ module DryCrud
|
|
60
61
|
|
61
62
|
# Class methods from GenericModel.
|
62
63
|
module ClassMethods
|
64
|
+
|
63
65
|
# The ActiveRecord class of the model.
|
64
66
|
def model_class
|
65
67
|
@model_class ||= controller_name.classify.constantize
|
@@ -79,7 +81,7 @@ module DryCrud
|
|
79
81
|
|
80
82
|
model_class.model_name.human(opts)
|
81
83
|
end
|
82
|
-
end
|
83
84
|
|
85
|
+
end
|
84
86
|
end
|
85
87
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
module DryCrud
|
4
|
+
|
4
5
|
# Provides functionality to nest controllers/resources.
|
5
6
|
# If a controller is nested, the parent classes and namespaces
|
6
7
|
# may be defined as an array in the +nesting+ class attribute.
|
@@ -9,24 +10,20 @@ module DryCrud
|
|
9
10
|
# namespace, may define this attribute as follows:
|
10
11
|
# self.nesting = :admin, Country
|
11
12
|
module Nestable
|
12
|
-
extend ActiveSupport::Concern
|
13
13
|
|
14
14
|
# Adds the :nesting class attribute and parent helper methods
|
15
15
|
# to the including controller.
|
16
|
-
|
17
|
-
class_attribute :nesting
|
18
|
-
|
19
|
-
helper_method :parent, :parents
|
16
|
+
def self.prepended(klass)
|
17
|
+
klass.class_attribute :nesting
|
20
18
|
|
21
|
-
|
22
|
-
alias_method_chain :model_scope, :nesting
|
19
|
+
klass.helper_method :parent, :parents
|
23
20
|
end
|
24
21
|
|
25
22
|
private
|
26
23
|
|
27
24
|
# Returns the direct parent ActiveRecord of the current request, if any.
|
28
25
|
def parent
|
29
|
-
parents.
|
26
|
+
parents.reverse.find { |p| p.is_a?(ActiveRecord::Base) }
|
30
27
|
end
|
31
28
|
|
32
29
|
# Returns the parent entries of the current request, if any.
|
@@ -49,16 +46,16 @@ module DryCrud
|
|
49
46
|
end
|
50
47
|
|
51
48
|
# An array of objects used in url_for and related functions.
|
52
|
-
def
|
49
|
+
def path_args(last)
|
53
50
|
parents + [last]
|
54
51
|
end
|
55
52
|
|
56
53
|
# Uses the parent entry (if any) to constrain the model scope.
|
57
|
-
def
|
54
|
+
def model_scope
|
58
55
|
if parent.present?
|
59
56
|
parent_scope
|
60
57
|
else
|
61
|
-
|
58
|
+
super
|
62
59
|
end
|
63
60
|
end
|
64
61
|
|
@@ -66,5 +63,6 @@ module DryCrud
|
|
66
63
|
def parent_scope
|
67
64
|
parent.send(model_class.name.underscore.pluralize)
|
68
65
|
end
|
66
|
+
|
69
67
|
end
|
70
68
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
module DryCrud
|
4
|
+
|
4
5
|
# Remembers certain params of the index action in order to return
|
5
6
|
# to the same list after an entry was viewed or edited.
|
6
7
|
# If the index is called with a param :returning, the remembered params
|
@@ -12,13 +13,14 @@ module DryCrud
|
|
12
13
|
# The params are stored separately for each different +remember_key+, which
|
13
14
|
# defaults to the current request's path.
|
14
15
|
module Rememberable
|
16
|
+
|
15
17
|
extend ActiveSupport::Concern
|
16
18
|
|
17
19
|
included do
|
18
20
|
class_attribute :remember_params
|
19
21
|
self.remember_params = %w(q sort sort_dir page)
|
20
22
|
|
21
|
-
|
23
|
+
before_action :handle_remember_params, only: [:index]
|
22
24
|
end
|
23
25
|
|
24
26
|
private
|
@@ -53,6 +55,7 @@ module DryCrud
|
|
53
55
|
def remembered_params
|
54
56
|
session[:list_params] ||= {}
|
55
57
|
session[:list_params][remember_key] ||= {}
|
58
|
+
session[:list_params][remember_key]
|
56
59
|
end
|
57
60
|
|
58
61
|
# Params are stored by request path to play nice when a controller
|
@@ -60,5 +63,6 @@ module DryCrud
|
|
60
63
|
def remember_key
|
61
64
|
request.path
|
62
65
|
end
|
66
|
+
|
63
67
|
end
|
64
68
|
end
|
@@ -1,46 +1,67 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
module DryCrud
|
4
|
+
|
4
5
|
# Provide +before_render+ callbacks.
|
5
6
|
module RenderCallbacks
|
7
|
+
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
8
10
|
included do
|
9
11
|
extend ActiveModel::Callbacks
|
10
|
-
|
11
|
-
alias_method_chain :render, :callbacks
|
12
|
+
prepend Prepends
|
12
13
|
end
|
13
14
|
|
14
|
-
#
|
15
|
-
|
16
|
-
def render_with_callbacks(*args, &block)
|
17
|
-
options = _normalize_render(*args, &block)
|
18
|
-
callback = "render_#{options[:template]}"
|
15
|
+
# Prepended methods for callbacks.
|
16
|
+
module Prepends
|
19
17
|
|
20
|
-
|
18
|
+
# Helper method to run +before_render+ callbacks and render the action.
|
19
|
+
# If a callback renders or redirects, the action is not rendered.
|
20
|
+
def render(*args, &block)
|
21
|
+
options = _normalize_render(*args, &block)
|
22
|
+
callback = "render_#{options[:template]}"
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
+
run_callbacks(callback) if respond_to?(:"_#{callback}_callbacks", true)
|
25
|
+
|
26
|
+
super(*args, &block) unless performed?
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
24
30
|
|
25
|
-
|
31
|
+
# Helper method the run the given block in between the before and after
|
32
|
+
# callbacks of the given kinds.
|
33
|
+
def with_callbacks(*kinds, &block)
|
34
|
+
kinds.reverse.reduce(block) do |a, e|
|
35
|
+
-> { run_callbacks(e, &a) }
|
36
|
+
end.call
|
37
|
+
end
|
26
38
|
|
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
39
|
end
|
34
40
|
|
35
41
|
# Class methods for callbacks.
|
36
42
|
module ClassMethods
|
43
|
+
|
37
44
|
# Defines before callbacks for the render actions.
|
38
45
|
def define_render_callbacks(*actions)
|
39
46
|
args = actions.map { |a| :"render_#{a}" }
|
40
|
-
|
41
|
-
args << { only: :before, terminator: terminator }
|
47
|
+
args << { only: :before, terminator: render_callback_terminator }
|
42
48
|
define_model_callbacks(*args)
|
43
49
|
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def render_callback_terminator
|
54
|
+
proc do |ctrl, result_lambda|
|
55
|
+
terminate = true
|
56
|
+
catch(:abort) do
|
57
|
+
result_lambda.call if result_lambda.is_a?(Proc)
|
58
|
+
terminate = !ctrl.response_body.nil?
|
59
|
+
end
|
60
|
+
terminate
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
44
64
|
end
|
65
|
+
|
45
66
|
end
|
46
67
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
module DryCrud
|
4
|
+
|
4
5
|
# The search functionality for the index table.
|
5
6
|
# Define an array of searchable string columns in your subclassing
|
6
7
|
# controllers using the class attribute +search_columns+.
|
7
8
|
module Searchable
|
9
|
+
|
8
10
|
extend ActiveSupport::Concern
|
9
11
|
|
10
12
|
included do
|
@@ -13,49 +15,55 @@ module DryCrud
|
|
13
15
|
|
14
16
|
helper_method :search_support?
|
15
17
|
|
16
|
-
|
18
|
+
prepend Prepends
|
17
19
|
end
|
18
20
|
|
19
|
-
|
21
|
+
# Prepended methods for searching.
|
22
|
+
module Prepends
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
private
|
25
|
+
|
26
|
+
# Enhance the list entries with an optional search criteria
|
27
|
+
def list_entries
|
28
|
+
super.where(search_conditions)
|
29
|
+
end
|
25
30
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
# Concat the word clauses with AND.
|
32
|
+
def search_conditions
|
33
|
+
if search_support? && params[:q].present?
|
34
|
+
search_word_conditions.reduce do |query, condition|
|
35
|
+
query.and(condition)
|
36
|
+
end
|
31
37
|
end
|
32
38
|
end
|
33
|
-
end
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
40
|
+
# Split the search query in single words and create a list of word
|
41
|
+
# clauses.
|
42
|
+
def search_word_conditions
|
43
|
+
params[:q].split(/\s+/).map { |w| search_word_condition(w) }
|
44
|
+
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
# Concat the column queries of the given word with OR.
|
47
|
+
def search_word_condition(word)
|
48
|
+
search_column_condition(word).reduce do |query, condition|
|
49
|
+
query.or(condition)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create a list of Arel #matches queries for each column and the given
|
54
|
+
# word.
|
55
|
+
def search_column_condition(word)
|
56
|
+
self.class.search_tables_and_fields.map do |table_name, field|
|
57
|
+
table = Arel::Table.new(table_name)
|
58
|
+
table[field].matches(Arel::Nodes::Quoted.new("%#{word}%"))
|
59
|
+
end
|
44
60
|
end
|
45
|
-
end
|
46
61
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
self.class.search_tables_and_fields.map do |table_name, field|
|
51
|
-
table = Arel::Table.new(table_name)
|
52
|
-
table[field].matches("%#{word}%")
|
62
|
+
# Returns true if this controller has searchable columns.
|
63
|
+
def search_support?
|
64
|
+
search_columns.present?
|
53
65
|
end
|
54
|
-
end
|
55
66
|
|
56
|
-
# Returns true if this controller has searchable columns.
|
57
|
-
def search_support?
|
58
|
-
search_columns.present?
|
59
67
|
end
|
60
68
|
|
61
69
|
# Class methods for Searchable.
|
@@ -71,6 +79,7 @@ module DryCrud
|
|
71
79
|
end
|
72
80
|
end
|
73
81
|
end
|
82
|
+
|
74
83
|
end
|
75
84
|
|
76
85
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
module DryCrud
|
4
|
+
|
4
5
|
# Sort functionality for the index table.
|
5
6
|
# Define a default sort expression that is always appended to the
|
6
7
|
# current sort params with the class attribute +default_sort+.
|
7
8
|
module Sortable
|
9
|
+
|
8
10
|
extend ActiveSupport::Concern
|
9
11
|
|
10
12
|
included do
|
@@ -15,11 +17,12 @@ module DryCrud
|
|
15
17
|
|
16
18
|
helper_method :sortable?
|
17
19
|
|
18
|
-
|
20
|
+
prepend Prepends
|
19
21
|
end
|
20
22
|
|
21
23
|
# Class methods for sorting.
|
22
24
|
module ClassMethods
|
25
|
+
|
23
26
|
# Define a map of (virtual) attributes to SQL order expressions.
|
24
27
|
# May be used for sorting table columns that do not appear directly
|
25
28
|
# in the database table. E.g., map city_id: 'cities.name' to
|
@@ -28,38 +31,45 @@ module DryCrud
|
|
28
31
|
self.sort_mappings_with_indifferent_access =
|
29
32
|
hash.with_indifferent_access
|
30
33
|
end
|
34
|
+
|
31
35
|
end
|
32
36
|
|
33
|
-
|
37
|
+
# Prepended methods for sorting.
|
38
|
+
module Prepends
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
private
|
41
|
+
|
42
|
+
# Enhance the list entries with an optional sort order.
|
43
|
+
def list_entries
|
44
|
+
sortable = sortable?(params[:sort])
|
45
|
+
if sortable || default_sort
|
46
|
+
clause = [sortable ? sort_expression : nil, default_sort]
|
47
|
+
super.reorder(clause.compact.join(', '))
|
48
|
+
else
|
49
|
+
super
|
50
|
+
end
|
43
51
|
end
|
44
|
-
end
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
53
|
+
# Return the sort expression to be used in the list query.
|
54
|
+
def sort_expression
|
55
|
+
col = sort_mappings_with_indifferent_access[params[:sort]] ||
|
56
|
+
"#{model_class.table_name}.#{params[:sort]}"
|
57
|
+
"#{col} #{sort_dir}"
|
58
|
+
end
|
52
59
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
60
|
+
# The sort direction, either 'asc' or 'desc'.
|
61
|
+
def sort_dir
|
62
|
+
params[:sort_dir] == 'desc' ? 'DESC' : 'ASC'
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns true if the passed attribute is sortable.
|
66
|
+
def sortable?(attr)
|
67
|
+
attr.present? && (
|
68
|
+
model_class.column_names.include?(attr.to_s) ||
|
69
|
+
sort_mappings_with_indifferent_access.include?(attr))
|
70
|
+
end
|
57
71
|
|
58
|
-
# Returns true if the passed attribute is sortable.
|
59
|
-
def sortable?(attr)
|
60
|
-
attr.present? && (
|
61
|
-
model_class.column_names.include?(attr.to_s) ||
|
62
|
-
sort_mappings_with_indifferent_access.include?(attr))
|
63
72
|
end
|
73
|
+
|
64
74
|
end
|
65
75
|
end
|