e9_rails 0.0.10 → 0.0.11
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/lib/e9_rails/active_record/inheritable_options.rb +26 -6
- data/lib/e9_rails/active_record/initialization.rb +20 -0
- data/lib/e9_rails/controllers/orderable.rb +69 -40
- data/lib/e9_rails/controllers/sortable.rb +17 -1
- data/lib/e9_rails/helpers/resource_error_messages.rb +3 -3
- data/lib/e9_rails/helpers/resource_links.rb +84 -0
- data/lib/e9_rails/version.rb +1 -1
- data/lib/e9_rails.rb +5 -3
- metadata +4 -2
@@ -7,6 +7,11 @@ module E9Rails::ActiveRecord
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
included do
|
10
|
+
#
|
11
|
+
# NOTE
|
12
|
+
#
|
13
|
+
attribute_method_suffix "_with_inheritable_options"
|
14
|
+
|
10
15
|
class_inheritable_accessor :options_column
|
11
16
|
self.options_column = :options
|
12
17
|
|
@@ -16,16 +21,17 @@ module E9Rails::ActiveRecord
|
|
16
21
|
class_inheritable_accessor :options_class
|
17
22
|
self.options_class = Options
|
18
23
|
|
24
|
+
class_inheritable_accessor :delegate_options_methods
|
25
|
+
self.delegate_options_methods = false
|
26
|
+
|
19
27
|
self.options_class.lookup_ancestors = lookup_ancestors
|
20
28
|
end
|
21
29
|
|
22
30
|
def options=(hash={})
|
23
|
-
_serialize_inheritable_options_column unless _inheritable_options_column_serialized?
|
24
31
|
write_attribute(options_column, hash.stringify_keys)
|
25
32
|
end
|
26
33
|
|
27
34
|
def options
|
28
|
-
_serialize_inheritable_options_column unless _inheritable_options_column_serialized?
|
29
35
|
opts = read_attribute(options_column) || {}
|
30
36
|
opts.reverse_merge! Hash[options_parameters.map(&:to_s).zip([nil])]
|
31
37
|
options_class.new(opts, self)
|
@@ -33,18 +39,32 @@ module E9Rails::ActiveRecord
|
|
33
39
|
|
34
40
|
protected
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
module ClassMethods
|
43
|
+
def define_method_attribute_with_inheritable_options(attr_name)
|
44
|
+
initialize_inheritable_options
|
45
|
+
end
|
46
|
+
|
47
|
+
def inheritable_options_initialized?
|
48
|
+
serialized_attributes[self.options_column.to_s].present?
|
38
49
|
end
|
39
50
|
|
40
|
-
def
|
41
|
-
|
51
|
+
def initialize_inheritable_options
|
52
|
+
return if inheritable_options_initialized?
|
53
|
+
serialized_attributes[self.options_column.to_s] = Hash
|
54
|
+
|
55
|
+
if self.delegate_options_methods
|
56
|
+
self.options_parameters.each do |param|
|
57
|
+
delegate param, "#{param}=", :to => :options
|
58
|
+
end
|
59
|
+
end
|
42
60
|
end
|
61
|
+
end
|
43
62
|
|
44
63
|
class Options < HashWithIndifferentAccess
|
45
64
|
extend ActiveModel::Naming
|
46
65
|
extend ActiveModel::Translation
|
47
66
|
|
67
|
+
# implementation of lookup_ancestors for AM & i18n
|
48
68
|
class_inheritable_accessor :lookup_ancestors
|
49
69
|
|
50
70
|
attr_reader :base
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module E9Rails::ActiveRecord
|
2
|
+
module Initialization
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
alias :initialize_without_defaults :initialize
|
7
|
+
|
8
|
+
def initialize(attributes = nil, &block)
|
9
|
+
initialize_without_defaults(attributes) do
|
10
|
+
self.send(:_assign_initialization_defaults)
|
11
|
+
yield self if block_given?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def _assign_initialization_defaults; end
|
17
|
+
|
18
|
+
protected :_assign_initialization_defaults
|
19
|
+
end
|
20
|
+
end
|
@@ -6,51 +6,80 @@ module E9Rails::Controllers
|
|
6
6
|
module Orderable
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
def default_ordered_dir; 'DESC' end
|
9
|
+
included do
|
10
|
+
helper HelperMethods
|
12
11
|
|
13
|
-
|
12
|
+
helper_method :default_ordered_dir
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
when /^asc$/i then 'ASC'
|
23
|
-
else controller.send(:default_ordered_dir) rescue ''
|
24
|
-
end
|
25
|
-
|
26
|
-
# split the ordered_param on commas and periods, the idea being that
|
27
|
-
# it can take multiple columns, and on assocation columns
|
28
|
-
val = val.split(',').map {|v| v.split('.') }
|
29
|
-
|
30
|
-
val = val.map {|v|
|
31
|
-
# if val split on '.', try to constantize the parsed class
|
32
|
-
if v.length > 1
|
33
|
-
klass = v.first.classify.constantize rescue nil
|
34
|
-
# and if it succeeds
|
35
|
-
if klass
|
36
|
-
# apply the join to the scope.
|
37
|
-
# NOTE there's no checking whatsoever here as to:
|
38
|
-
# A.) is this class an association?
|
39
|
-
# B.) does this class have the passed column?
|
40
|
-
scope = scope.joins(v.first.underscore.to_sym)
|
41
|
-
"#{klass.table_name}.#{v.last} #{dir}"
|
14
|
+
has_scope :order, :if => :ordered_if, :default => lambda {|c| c.send(:default_ordered_on) } do |controller, scope, columns|
|
15
|
+
begin
|
16
|
+
# determine the dir from params or controller default
|
17
|
+
dir = case controller.params[:sort]
|
18
|
+
when /^desc$/i then 'DESC'
|
19
|
+
when /^asc$/i then 'ASC'
|
20
|
+
else controller.try(:default_ordered_dir) || ''
|
42
21
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
22
|
+
|
23
|
+
# split the ordered_param on commas and periods, the idea being that
|
24
|
+
# it can take multiple columns, and on assocation columns
|
25
|
+
columns = columns.split(',').map {|n| n.split('.') }
|
26
|
+
|
27
|
+
columns = columns.map {|v|
|
28
|
+
# if column split on '.', try to constantize the parsed class
|
29
|
+
if v.length > 1
|
30
|
+
klass = v.first.classify.constantize rescue nil
|
31
|
+
|
32
|
+
# and if it succeeds
|
33
|
+
if klass
|
34
|
+
# apply the join to the scope.
|
35
|
+
# NOTE there's no checking whatsoever here as to:
|
36
|
+
# A.) is this class an association?
|
37
|
+
# B.) does this class have the passed column?
|
38
|
+
scope = scope.includes(v.first.underscore.to_sym)
|
39
|
+
"#{klass.table_name}.#{v.last} #{dir}"
|
46
40
|
end
|
47
|
-
|
41
|
+
else
|
42
|
+
# else we're assuming the column is on the table
|
43
|
+
"#{controller.send(:resource_class).table_name}.#{v.last} #{dir}"
|
44
|
+
end
|
45
|
+
}.compact.join(', ')
|
46
|
+
|
47
|
+
scope.order(columns)
|
48
|
+
rescue => e
|
49
|
+
Rails.logger.error("Orderable ordered_on scope : #{e.message}")
|
50
|
+
scope
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def default_ordered_on
|
56
|
+
'created_at'
|
57
|
+
end
|
58
|
+
|
59
|
+
def default_ordered_dir
|
60
|
+
'DESC'
|
61
|
+
end
|
62
|
+
|
63
|
+
def ordered_if
|
64
|
+
params[:action] == 'index'
|
65
|
+
end
|
66
|
+
|
67
|
+
module HelperMethods
|
68
|
+
def orderable_column_link(column, override_name = nil)
|
69
|
+
link_text = resource_class.human_attribute_name(override_name || column)
|
70
|
+
|
71
|
+
column = column.join(',') if column.is_a?(Array)
|
72
|
+
|
73
|
+
co, lo = if params[:order] == column.to_s
|
74
|
+
params[:sort] =~ /^desc$/i ? %w(DESC ASC) : %w(ASC DESC)
|
75
|
+
else
|
76
|
+
[nil, default_ordered_dir.presence || 'DESC']
|
77
|
+
end
|
78
|
+
|
79
|
+
css_classes = ["order-gfx", co, "h-#{lo}"].compact.join(' ').downcase
|
48
80
|
|
49
|
-
|
50
|
-
|
51
|
-
Rails.logger.error("Orderable ordered_on scope : #{e.message}")
|
52
|
-
scope
|
53
|
-
end
|
81
|
+
content_tag(:div, :class => 'ordered-column') do
|
82
|
+
link_to(link_text, :order => column, :sort => lo).safe_concat tag(:span, :class => css_classes)
|
54
83
|
end
|
55
84
|
end
|
56
85
|
end
|
@@ -12,10 +12,26 @@ module E9Rails::Controllers
|
|
12
12
|
module Sortable
|
13
13
|
extend ActiveSupport::Concern
|
14
14
|
|
15
|
+
included do
|
16
|
+
class_inheritable_accessor :sortable_column
|
17
|
+
self.sortable_column = :position
|
18
|
+
|
19
|
+
class_inheritable_accessor :sortable_scope_proc
|
20
|
+
self.sortable_scope_proc = lambda {|_, scope, _| scope.order(sortable_column) }
|
21
|
+
|
22
|
+
#
|
23
|
+
# NOTE whatever the sortable column value, the proc will override the default.
|
24
|
+
# the 'default' is only specified here to ensure that the scope is always called
|
25
|
+
#
|
26
|
+
has_scope :sortable_order, :only => :index, :default => sortable_column.to_s do |controller, scope, value|
|
27
|
+
sortable_scope_proc.call(controller, scope, value)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
15
31
|
def update_order(options = {}, &block)
|
16
32
|
if params[:ids].is_a?(Array)
|
17
33
|
pos = 0
|
18
|
-
params[:ids].each {|id| pos += 1; _do_position_update(id,
|
34
|
+
params[:ids].each {|id| pos += 1; _do_position_update(id, sortable_column => pos) }
|
19
35
|
flash[:notice] = I18n.t(:notice, :scope => :"flash.actions.update_order")
|
20
36
|
else
|
21
37
|
flash[:alert] = I18n.t(:alert, :scope => :"flash.actions.update_order")
|
@@ -23,11 +23,11 @@ module E9Rails::Helpers
|
|
23
23
|
return ''
|
24
24
|
end
|
25
25
|
|
26
|
+
errors = object.errors.map {|attribute, msg| msg }.flatten.map {|m| "<li>#{m}</li>"}.join("\n")
|
27
|
+
|
26
28
|
<<-HTML.html_safe
|
27
29
|
<div id="errorExplanation">
|
28
|
-
<ul>
|
29
|
-
#{ object.errors.map {|attribute, msg| "<li>#{msg}</li>" }.join }
|
30
|
-
</ul>
|
30
|
+
<ul>#{errors}</ul>
|
31
31
|
</div>
|
32
32
|
HTML
|
33
33
|
rescue => e
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module E9Rails::Helpers
|
2
|
+
module ResourceLinks
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
helper HelperMethods
|
7
|
+
|
8
|
+
unless self._helper_methods.member?(:parent)
|
9
|
+
def parent; end
|
10
|
+
protected :parent
|
11
|
+
helper_method :parent
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module HelperMethods
|
16
|
+
def link_to_resource(resource, options = {})
|
17
|
+
options.symbolize_keys!
|
18
|
+
|
19
|
+
path_options = options.slice!(:scope, :action, :method, :remote, :confirm, :class)
|
20
|
+
|
21
|
+
klass = resource.is_a?(Class) ? resource : resource.class
|
22
|
+
|
23
|
+
action = options.delete(:action)
|
24
|
+
action = klass == resource ? :new : (action || :show).to_sym
|
25
|
+
|
26
|
+
scopes = [*(options[:scope] || @route_scope), parent].compact
|
27
|
+
path = case action
|
28
|
+
when :new; new_polymorphic_path(scopes << klass, path_options)
|
29
|
+
when :edit; edit_polymorphic_path(scopes << resource, path_options)
|
30
|
+
else polymorphic_path(scopes << resource, path_options)
|
31
|
+
end
|
32
|
+
|
33
|
+
mn = klass.model_name
|
34
|
+
|
35
|
+
translation_options = {
|
36
|
+
:model => mn.human,
|
37
|
+
:models => mn.human.pluralize,
|
38
|
+
:collection => mn.collection,
|
39
|
+
:element => mn.element
|
40
|
+
}
|
41
|
+
|
42
|
+
if action == :destroy
|
43
|
+
defaults = klass.lookup_ancestors.map {|k|
|
44
|
+
:"#{klass.i18n_scope}.links.#{k.model_name.underscore}.confirm_destroy"
|
45
|
+
} << :"#{klass.i18n_scope}.links.confirm_destroy"
|
46
|
+
|
47
|
+
options[:method] = :delete
|
48
|
+
options.reverse_merge!({
|
49
|
+
:remote => true,
|
50
|
+
:confirm => I18n.t(defaults.shift, translation_options.merge(:default => defaults))
|
51
|
+
})
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Mimic ActiveModel's lookup chain for attributes
|
56
|
+
#
|
57
|
+
defaults = klass.lookup_ancestors.map do |k|
|
58
|
+
:"#{klass.i18n_scope}.links.#{k.model_name.underscore}.#{action}"
|
59
|
+
end
|
60
|
+
|
61
|
+
defaults << :"#{klass.i18n_scope}.links.#{action}"
|
62
|
+
defaults << action.to_s.humanize
|
63
|
+
|
64
|
+
link_to I18n.t(defaults.shift, translation_options.merge(:default => defaults)), path, options
|
65
|
+
end
|
66
|
+
|
67
|
+
def link_to_show_resource(resource, options = {})
|
68
|
+
link_to_resource(resource, options.merge(:action => :show))
|
69
|
+
end
|
70
|
+
|
71
|
+
def link_to_edit_resource(resource, options = {})
|
72
|
+
link_to_resource(resource, options.merge(:action => :edit))
|
73
|
+
end
|
74
|
+
|
75
|
+
def link_to_new_resource(resource, options = {})
|
76
|
+
link_to_resource(resource, options.merge(:action => :new))
|
77
|
+
end
|
78
|
+
|
79
|
+
def link_to_destroy_resource(resource, options = {})
|
80
|
+
link_to_resource(resource, options.merge(:action => :destroy))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/e9_rails/version.rb
CHANGED
data/lib/e9_rails.rb
CHANGED
@@ -4,9 +4,10 @@ module E9Rails
|
|
4
4
|
autoload :Version, 'e9_rails/version'
|
5
5
|
|
6
6
|
module ActiveRecord
|
7
|
-
autoload :STI, 'e9_rails/active_record/sti'
|
8
7
|
autoload :AttributeSearchable, 'e9_rails/active_record/attribute_searchable'
|
9
8
|
autoload :InheritableOptions, 'e9_rails/active_record/inheritable_options'
|
9
|
+
autoload :Initialization, 'e9_rails/active_record/initialization'
|
10
|
+
autoload :STI, 'e9_rails/active_record/sti'
|
10
11
|
end
|
11
12
|
|
12
13
|
module Controllers
|
@@ -15,9 +16,10 @@ module E9Rails
|
|
15
16
|
end
|
16
17
|
|
17
18
|
module Helpers
|
18
|
-
autoload :
|
19
|
+
autoload :Pagination, 'e9_rails/helpers/pagination'
|
19
20
|
autoload :ResourceErrorMessages, 'e9_rails/helpers/resource_error_messages'
|
21
|
+
autoload :ResourceLinks, 'e9_rails/helpers/resource_links'
|
20
22
|
autoload :Title, 'e9_rails/helpers/title'
|
21
|
-
autoload :
|
23
|
+
autoload :Translation, 'e9_rails/helpers/translation'
|
22
24
|
end
|
23
25
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: e9_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.11
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Travis Cox
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-12 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -53,11 +53,13 @@ files:
|
|
53
53
|
- lib/e9_rails.rb
|
54
54
|
- lib/e9_rails/active_record/attribute_searchable.rb
|
55
55
|
- lib/e9_rails/active_record/inheritable_options.rb
|
56
|
+
- lib/e9_rails/active_record/initialization.rb
|
56
57
|
- lib/e9_rails/active_record/sti.rb
|
57
58
|
- lib/e9_rails/controllers/orderable.rb
|
58
59
|
- lib/e9_rails/controllers/sortable.rb
|
59
60
|
- lib/e9_rails/helpers/pagination.rb
|
60
61
|
- lib/e9_rails/helpers/resource_error_messages.rb
|
62
|
+
- lib/e9_rails/helpers/resource_links.rb
|
61
63
|
- lib/e9_rails/helpers/title.rb
|
62
64
|
- lib/e9_rails/helpers/translation.rb
|
63
65
|
- lib/e9_rails/version.rb
|