resourcelogic 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +72 -40
- data/Rakefile +4 -4
- data/lib/resourcelogic.rb +3 -0
- data/lib/resourcelogic/accessors.rb +1 -1
- data/lib/resourcelogic/actions.rb +19 -52
- data/lib/resourcelogic/base.rb +33 -3
- data/lib/resourcelogic/child.rb +33 -73
- data/lib/resourcelogic/context.rb +24 -61
- data/lib/resourcelogic/parent.rb +68 -100
- data/lib/resourcelogic/self.rb +87 -123
- data/lib/resourcelogic/sibling.rb +4 -46
- data/lib/resourcelogic/singleton.rb +37 -55
- data/lib/resourcelogic/urligence.rb +77 -59
- data/lib/resourcelogic/version.rb +1 -1
- metadata +9 -7
data/lib/resourcelogic/child.rb
CHANGED
@@ -7,89 +7,49 @@ module Resourcelogic
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module Urls
|
10
|
-
def self.included(klass)
|
11
|
-
klass.helper_method :new_child_url, :new_child_path, :edit_child_url, :edit_child_path,
|
12
|
-
:child_url, :child_path, :child_collection_url, :child_collection_path
|
13
|
-
end
|
14
|
-
|
15
10
|
private
|
16
|
-
def new_child_url(child_name, url_params = {})
|
17
|
-
smart_url *new_child_url_options(child_name, url_params)
|
18
|
-
end
|
19
|
-
|
20
|
-
def new_child_path(child_name, url_params = {})
|
21
|
-
smart_path *new_child_url_options(child_name, url_params)
|
22
|
-
end
|
23
|
-
|
24
|
-
def edit_child_url(child, url_params = {})
|
25
|
-
smart_url *child_url_options(child, :edit, url_params)
|
26
|
-
end
|
27
|
-
|
28
|
-
def edit_child_path(child, url_params = {})
|
29
|
-
smart_path *child_url_options(child, :edit, url_params)
|
30
|
-
end
|
31
|
-
|
32
|
-
def child_url(child, url_params = {})
|
33
|
-
smart_url *child_url_options(child, url_params)
|
34
|
-
end
|
35
|
-
|
36
11
|
# The following should work
|
37
12
|
#
|
38
13
|
# child_path(obj)
|
39
14
|
# child_path(obj, :id => 2) # where obj is then replaced by the obj with id 2
|
40
15
|
# child_path(:child_name, :id => 2) # where this is a literal build of the url
|
41
|
-
def
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def child_collection_url(child_name, url_params = {})
|
46
|
-
smart_url *child_collection_url_options(child_name, url_params)
|
47
|
-
end
|
48
|
-
|
49
|
-
def child_collection_path(child_name, url_params = {})
|
50
|
-
smart_path *child_collection_url_options(child_name, url_params)
|
16
|
+
def child_url_parts(action = nil, child = nil, url_params = {})
|
17
|
+
child_base_parts(action, url_params) + [[child.is_a?(Symbol) ? child : child.class.name.underscore.to_sym, child], url_params]
|
51
18
|
end
|
52
19
|
|
53
|
-
def
|
54
|
-
|
20
|
+
def child_collection_url_parts(action = nil, child_name = nil, url_params = {})
|
21
|
+
child_base_parts(action, url_params) + [child_name, url_params]
|
55
22
|
end
|
56
23
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
when Symbol
|
87
|
-
action_prefix = action_prefix_or_params
|
88
|
-
when Hash
|
89
|
-
url_params = action_prefix_or_params
|
90
|
-
end
|
91
|
-
[action_prefix, url_params]
|
92
|
-
end
|
24
|
+
# This determines if the child if off of an object or the collection. Most of the time,
|
25
|
+
# as assumed, it will be off of an object. But let's say you are at this url:
|
26
|
+
#
|
27
|
+
# /payments
|
28
|
+
#
|
29
|
+
# And you call this path:
|
30
|
+
#
|
31
|
+
# child_collection(:credit_cards)
|
32
|
+
#
|
33
|
+
# There is no object to be a child off, we are in the collection / index action. But
|
34
|
+
# we still want to call the following url:
|
35
|
+
#
|
36
|
+
# /payments/credit_cards
|
37
|
+
#
|
38
|
+
# That's what this method does, it makes the above possible. So you can still link
|
39
|
+
# to the "child" credit cards resource relatively, keeping the idea of contextual
|
40
|
+
# development intact. Maybe you only want to use payments as a context for the
|
41
|
+
# credit cards resource.
|
42
|
+
def child_base_parts(action, url_params)
|
43
|
+
object_to_use = (url_params.key?("#{model_name}_id".to_sym) && url_params["#{model_name}_id".to_sym]) || (id? && object)
|
44
|
+
base_parts = object_to_use || singleton? ? object_url_parts(action, object_to_use) : collection_url_parts(action)
|
45
|
+
base_parts.pop if base_parts.last.is_a?(Hash)
|
46
|
+
base_parts
|
47
|
+
end
|
48
|
+
|
49
|
+
#def current_object_to_use(url_params)
|
50
|
+
# result = (url_params.key?("#{model_name}_id".to_sym) && url_params["#{model_name}_id".to_sym]) || (id? && object)
|
51
|
+
# result ? result : nil
|
52
|
+
#end
|
93
53
|
end
|
94
54
|
end
|
95
55
|
end
|
@@ -4,85 +4,48 @@ module Resourcelogic
|
|
4
4
|
module Context
|
5
5
|
def self.included(klass)
|
6
6
|
klass.class_eval do
|
7
|
-
extend Config
|
8
7
|
add_acts_as_resource_module(Methods)
|
9
8
|
end
|
10
9
|
end
|
11
10
|
|
12
|
-
module Config
|
13
|
-
def contextual_views(value = nil)
|
14
|
-
config(:contextual_views, value)
|
15
|
-
end
|
16
|
-
|
17
|
-
def contextual_views?
|
18
|
-
!contextual_views.blank?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
11
|
module Methods
|
23
12
|
def self.included(klass)
|
24
|
-
klass.helper_method :context, :contexts, :
|
13
|
+
klass.helper_method :context, :contexts, :contexts_url_parts
|
14
|
+
klass.hide_action :context, :contexts
|
25
15
|
end
|
26
16
|
|
27
|
-
|
28
|
-
|
29
|
-
|
17
|
+
def context
|
18
|
+
@context ||= contexts.last
|
19
|
+
end
|
20
|
+
|
21
|
+
def contexts
|
22
|
+
return @contexts if defined?(@contexts)
|
23
|
+
path_parts = request.path.split("/")
|
24
|
+
path_parts.shift
|
25
|
+
@contexts = []
|
26
|
+
path_parts.each_with_index do |part, index|
|
27
|
+
break if model_name_from_path_part(part.split(".").first) == model_name
|
28
|
+
@contexts << (part.to_i > 0 ? @contexts.pop.to_s.singularize.to_sym : part.underscore.to_sym)
|
30
29
|
end
|
30
|
+
@contexts
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
def
|
34
|
-
return @
|
33
|
+
private
|
34
|
+
def contexts_url_parts
|
35
|
+
return @contexts_url_parts if @contexts_url_parts
|
35
36
|
path_parts = request.path.split("/")
|
36
37
|
path_parts.shift
|
37
|
-
@
|
38
|
+
@contexts_url_parts = []
|
38
39
|
path_parts.each_with_index do |part, index|
|
39
|
-
|
40
|
-
break if [(parent_alias || parent_model_name).to_s.pluralize, (parent_alias || parent_model_name).to_s, route_name.to_s.pluralize].include?(part.underscore)
|
40
|
+
break if model_name_from_path_part(part.split(".").first) == model_name
|
41
41
|
if part.to_i > 0
|
42
|
-
@
|
42
|
+
@contexts_url_parts << [route_name_from_path_part(@contexts_url_parts.pop), part.to_i]
|
43
43
|
else
|
44
|
-
@
|
44
|
+
@contexts_url_parts << part.underscore.to_sym
|
45
45
|
end
|
46
46
|
end
|
47
|
-
@
|
48
|
-
end
|
49
|
-
alias_method :namespaces, :contexts
|
50
|
-
|
51
|
-
def contextual_views?
|
52
|
-
self.class.contextual_views?
|
53
|
-
end
|
54
|
-
|
55
|
-
def contextual_views
|
56
|
-
self.class.contextual_views
|
57
|
-
end
|
58
|
-
|
59
|
-
def context_template_name(name)
|
60
|
-
sub_folder = contextual_views.is_a?(Hash) && contextual_views.key?(context) ? contextual_views[context] : context
|
61
|
-
sub_folder ||= "root"
|
62
|
-
"#{controller_name}/#{sub_folder}/#{name}"
|
63
|
-
end
|
64
|
-
|
65
|
-
def default_template_name(action_name = self.action_name)
|
66
|
-
if contextual_views?
|
67
|
-
context_template_name(action_name)
|
68
|
-
else
|
69
|
-
super
|
70
|
-
end
|
47
|
+
@contexts_url_parts
|
71
48
|
end
|
72
49
|
end
|
73
|
-
|
74
|
-
module Partials
|
75
|
-
def _pick_partial_template(partial_path)
|
76
|
-
partial_path = context_template_name(partial_path) if respond_to?(:contextual_views?) && contextual_views? && !partial_path.include?("/")
|
77
|
-
super
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
module ActionView
|
85
|
-
class Base
|
86
|
-
include Resourcelogic::Context::Partials
|
87
50
|
end
|
88
51
|
end
|
data/lib/resourcelogic/parent.rb
CHANGED
@@ -17,157 +17,125 @@ module Resourcelogic
|
|
17
17
|
@belongs_to[name.to_sym] = options
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
def require_parent(value = nil)
|
22
|
+
rw_config(:require_parent, value, false)
|
23
|
+
end
|
20
24
|
end
|
21
25
|
|
22
26
|
module Urls
|
23
|
-
def self.included(klass)
|
24
|
-
klass.helper_method :new_parent_url, :new_parent_path, :edit_parent_url, :edit_parent_path, :parent_url, :parent_path,
|
25
|
-
:parent_collection_url, :parent_collection_path
|
26
|
-
end
|
27
|
-
|
28
27
|
private
|
29
|
-
def
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def new_parent_path(url_params = {})
|
34
|
-
smart_path *([:new] + namespaces + [parent_url_options, url_params])
|
35
|
-
end
|
36
|
-
|
37
|
-
def edit_parent_url(url_params = {})
|
38
|
-
smart_url *([:edit] + namespaces + [parent_url_options, url_params])
|
39
|
-
end
|
40
|
-
|
41
|
-
def edit_parent_path(url_params = {})
|
42
|
-
smart_path *([:edit] + namespaces + [parent_url_options, url_params])
|
43
|
-
end
|
44
|
-
|
45
|
-
def parent_url(url_params = {})
|
46
|
-
smart_url *(namespaces + [parent_url_options, url_params])
|
28
|
+
def parent_url_parts(action = nil, url_params = {})
|
29
|
+
[action] + contexts_url_parts + [url_params]
|
47
30
|
end
|
48
31
|
|
49
|
-
def
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def parent_collection_url(url_params = {})
|
54
|
-
smart_url *(namespaces + [parent_model_name.to_s.pluralize.to_sym, url_params])
|
55
|
-
end
|
56
|
-
|
57
|
-
def parent_collection_path(url_params = {})
|
58
|
-
smart_path *(namespaces + [parent_model_name.to_s.pluralize.to_sym, url_params])
|
59
|
-
end
|
60
|
-
|
61
|
-
def parent_url_options
|
62
|
-
if parent?
|
63
|
-
parent_name = (parent_alias || parent_model_name).to_sym
|
64
|
-
parent_singleton? ? parent_name : [parent_name, parent_object]
|
65
|
-
else
|
66
|
-
nil
|
67
|
-
end
|
32
|
+
def parent_collection_url_parts(*args)
|
33
|
+
parent_url_parts(*args)
|
68
34
|
end
|
69
35
|
end
|
70
36
|
|
71
37
|
module Reflection
|
72
38
|
def self.included(klass)
|
73
|
-
klass.
|
39
|
+
klass.class_eval do
|
40
|
+
helper_method :parent?, :parent_model_name, :parent_object
|
41
|
+
before_filter :require_parent
|
42
|
+
end
|
74
43
|
end
|
75
44
|
|
76
45
|
private
|
77
46
|
def belongs_to
|
78
47
|
self.class.belongs_to
|
79
48
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
49
|
+
|
50
|
+
def parent_path_name
|
51
|
+
return @parent_path_name if defined?(@parent_path_name)
|
52
|
+
path_parts = request.path.split("/")
|
53
|
+
path_parts.reverse.each do |path_part|
|
54
|
+
next if path_part.blank?
|
55
|
+
if model_name_from_path_part(path_part) == parent_model_name
|
56
|
+
return @parent_path_name = path_part.to_sym
|
57
|
+
end
|
58
|
+
end
|
59
|
+
@parent_path_name = nil
|
85
60
|
end
|
86
|
-
|
87
|
-
def
|
88
|
-
return @
|
89
|
-
|
90
|
-
|
61
|
+
|
62
|
+
def parent_route_name
|
63
|
+
return @parent_route_name if defined?(@parent_route_name)
|
64
|
+
path_parts = request.path.split("/")
|
65
|
+
path_parts.reverse.each do |path_part|
|
66
|
+
next if path_part.blank?
|
67
|
+
if model_name_from_path_part(path_part) == parent_model_name
|
68
|
+
return @parent_route_name = route_name_from_path_part(path_part)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@parent_route_name = parent_model_name
|
91
72
|
end
|
92
|
-
|
73
|
+
|
93
74
|
# Returns the type of the current parent
|
94
75
|
#
|
95
76
|
def parent_model_name
|
96
|
-
return @parent_model_name if @parent_model_name
|
97
|
-
|
77
|
+
return @parent_model_name if defined?(@parent_model_name)
|
78
|
+
parent_from_path?
|
98
79
|
@parent_model_name
|
99
80
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
def parent_from_params?
|
104
|
-
return @parent_from_params if defined?(@parent_from_params)
|
105
|
-
belongs_to.each do |model_name, options|
|
106
|
-
if !params["#{model_name}_id".to_sym].nil?
|
107
|
-
@parent_model_name = model_name
|
108
|
-
@parent_alias = options[:as]
|
109
|
-
return @parent_from_params = true
|
110
|
-
end
|
111
|
-
end
|
112
|
-
@parent_from_params = false
|
81
|
+
|
82
|
+
def parent_model
|
83
|
+
@parent_model ||= parent_model_name.to_s.camelize.constantize
|
113
84
|
end
|
114
|
-
|
85
|
+
|
115
86
|
# Returns the type of the current parent extracted form a request path
|
116
|
-
#
|
117
|
-
def
|
118
|
-
return @
|
87
|
+
#
|
88
|
+
def parent_from_path?
|
89
|
+
return @parent_from_path if defined?(@parent_from_path)
|
119
90
|
belongs_to.each do |model_name, options|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
91
|
+
request.path.split('/').reverse.each do |path_part|
|
92
|
+
possible_model_names(model_name).each_with_index do |possible_name, index|
|
93
|
+
if [possible_name.to_s, possible_name.to_s.pluralize].include?(path_part)
|
94
|
+
@parent_model_name = model_name
|
95
|
+
return @parent_from_path = true
|
96
|
+
end
|
97
|
+
end
|
124
98
|
end
|
125
99
|
end
|
126
|
-
@
|
100
|
+
@parent_from_path = false
|
127
101
|
end
|
128
|
-
|
102
|
+
|
129
103
|
# Returns true/false based on whether or not a parent is present.
|
130
104
|
#
|
131
105
|
def parent?
|
132
106
|
!parent_model_name.nil?
|
133
107
|
end
|
134
|
-
|
108
|
+
|
135
109
|
# Returns true/false based on whether or not a parent is a singleton.
|
136
|
-
#
|
110
|
+
#
|
137
111
|
def parent_singleton?
|
138
|
-
|
112
|
+
parent? && parent_id.nil?
|
139
113
|
end
|
140
|
-
|
114
|
+
|
141
115
|
# Returns the current parent param, if there is a parent. (i.e. params[:post_id])
|
142
|
-
def
|
143
|
-
params["#{
|
116
|
+
def parent_id
|
117
|
+
params["#{parent_route_name}_id".to_sym]
|
144
118
|
end
|
145
|
-
|
146
|
-
# Like the model method, but for a parent relationship.
|
147
|
-
#
|
148
|
-
def parent_model
|
149
|
-
@parent_model ||= parent_model_name.to_s.camelize.constantize
|
150
|
-
end
|
151
|
-
|
119
|
+
|
152
120
|
# Returns the current parent object if a parent object is present.
|
153
121
|
#
|
154
|
-
def parent_object
|
155
|
-
return @parent_object if defined?(@parent_object)
|
122
|
+
def parent_object(reload = false)
|
123
|
+
return @parent_object if !reload && defined?(@parent_object)
|
156
124
|
if parent?
|
157
125
|
if parent_singleton? && respond_to?("current_#{parent_model_name}", true)
|
158
126
|
@parent_object = send("current_#{parent_model_name}")
|
127
|
+
elsif parent_singleton? && parent_scope.respond_to?(parent_model_name)
|
128
|
+
@parent_object = parent_scope.send(parent_model_name, reload)
|
159
129
|
else
|
160
|
-
@parent_object =
|
130
|
+
@parent_object = parent_scope.find(parent_id)
|
161
131
|
end
|
162
132
|
else
|
163
133
|
@parent_object = nil
|
164
134
|
end
|
165
135
|
end
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
def end_of_association_chain
|
170
|
-
parent? ? parent_association : model
|
136
|
+
|
137
|
+
def require_parent
|
138
|
+
raise StandardError.new("A parent is required to access this resource and no parent was found") if !parent? && self.class.require_parent == true
|
171
139
|
end
|
172
140
|
end
|
173
141
|
end
|