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.
@@ -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 child_path(child, url_params = {})
42
- smart_path *child_url_options(child, url_params)
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 new_child_url_options(child_name, url_params = {})
54
- object_url_options(:new) + [child_name, url_params]
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
- def child_url_options(child, *action_prefix_or_params)
58
- action_prefix, url_params = identify_action_prefix_or_params(action_prefix_or_params)
59
- object_url_options(action_prefix) + [[child.is_a?(Symbol) ? child : child.class.name.underscore.to_sym, child], url_params]
60
- end
61
-
62
- def child_collection_url_options(child_name, url_params = {})
63
- object_url_options + [child_name, url_params]
64
- end
65
-
66
- def find_object_for_child(url_params = {})
67
- key = "#{model_name}_id".to_sym
68
- url_params.key?(key) ? end_of_association_chain.find(url_params[key]) : object
69
- end
70
-
71
- def find_child_name(child)
72
- name = args.first.class.name.underscore.to_sym
73
- return name if model.reflect_on_association(name)
74
-
75
- name = name.to_s.pluralize
76
- end
77
-
78
- def identify_action_prefix_or_params(action_prefix_or_params)
79
- action_prefix_or_params = action_prefix_or_params.first if action_prefix_or_params.is_a?(Array) && action_prefix_or_params.size <= 1
80
- action_prefix = nil
81
- url_params = {}
82
- case action_prefix_or_params
83
- when Array
84
- url_params = action_prefix_or_params.last if action_prefix_or_params.last.is_a?(Hash)
85
- action_prefix = action_prefix_or_params.first
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, :contextual_views, :contextual_views?, :context_template_name
13
+ klass.helper_method :context, :contexts, :contexts_url_parts
14
+ klass.hide_action :context, :contexts
25
15
  end
26
16
 
27
- private
28
- def context
29
- @context ||= (parent? && (parent_alias || parent_model_name)) || (contexts.last && (contexts.last.is_a?(Array) ? contexts.last.first : contexts.last))
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
- # Returns all of the current namespaces of the current controller, symbolized, in array form.
33
- def contexts
34
- return @contexts if @contexts
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
- @contexts = []
38
+ @contexts_url_parts = []
38
39
  path_parts.each_with_index do |part, index|
39
- part = part.split(".").first if (index + 1) == path_parts.size # for formats: blah.html or blah.js
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
- @contexts << [@contexts.pop.to_s.singularize.to_sym, part]
42
+ @contexts_url_parts << [route_name_from_path_part(@contexts_url_parts.pop), part.to_i]
43
43
  else
44
- @contexts << part.underscore.to_sym
44
+ @contexts_url_parts << part.underscore.to_sym
45
45
  end
46
46
  end
47
- @contexts
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
@@ -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 new_parent_url(url_params = {})
30
- smart_url *([:new] + namespaces + [parent_url_options, url_params])
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 parent_path(url_params = {})
50
- smart_path *(namespaces + [parent_url_options, url_params])
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.helper_method :parent?, :parent_model_name, :parent_object
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
- # Returns the relevant association proxy of the parent. (i.e. /posts/1/comments # => @post.comments)
82
- #
83
- def parent_association
84
- @parent_association ||= parent_object.send(model_name.to_s.pluralize.to_sym)
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 parent_alias
88
- return @parent_alias if @parent_alias
89
- parent_from_params? || parent_from_request?
90
- @parent_alias
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
- parent_from_params? || parent_from_request?
77
+ return @parent_model_name if defined?(@parent_model_name)
78
+ parent_from_path?
98
79
  @parent_model_name
99
80
  end
100
-
101
- # Returns the type of the current parent extracted from params
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 parent_from_request?
118
- return @parent_from_request if defined?(@parent_from_request)
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
- if request.path.split('/').include?((options[:as] && options[:as].to_s) || model_name.to_s)
121
- @parent_model_name = model_name
122
- @parent_alias = options[:as]
123
- return @parent_from_request = true
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
- @parent_from_request = false
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
- !parent_from_params?
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 parent_param
143
- params["#{parent_model_name}_id".to_sym]
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 = parent_model.find(parent_param)
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
- # If there is a parent, returns the relevant association proxy. Otherwise returns model.
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