resourcelogic 0.0.12 → 0.9.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.
@@ -10,13 +10,8 @@ module Resourcelogic
10
10
  end
11
11
 
12
12
  def method_missing(method_name, &block)
13
- existing = self[method_name]
14
- if existing
15
- existing[0] = method_name
16
- existing[1] = block || nil
17
- else
18
- @responses << [method_name, block || nil]
19
- end
13
+ @responses.delete self[method_name]
14
+ @responses << [method_name, block || nil]
20
15
  end
21
16
 
22
17
  def [](symbol)
@@ -3,145 +3,181 @@ module Resourcelogic
3
3
  def self.included(klass)
4
4
  klass.class_eval do
5
5
  extend Config
6
- add_acts_as_resource_module(UrlParts)
6
+ add_acts_as_resource_module(Urls)
7
7
  add_acts_as_resource_module(Reflection)
8
8
  end
9
9
  end
10
10
 
11
11
  module Config
12
12
  def model_name(value = nil)
13
- rw_config(:model_name, value, model_name_from_name)
13
+ config(:model_name, value, controller_name.singularize.underscore)
14
14
  end
15
15
 
16
16
  def object_name(value = nil)
17
- rw_config(:object_name, value, model_name_from_name)
17
+ config(:object_name, value, controller_name.singularize.underscore)
18
18
  end
19
19
 
20
- private
21
- def model_name_from_name
22
- name.underscore.split("/").first.gsub(/_controller/, "").singularize.underscore.to_sym
23
- end
20
+ def route_name(value = nil)
21
+ config(:route_name, value, controller_name.singularize.underscore)
22
+ end
24
23
  end
25
24
 
26
- module UrlParts
25
+ module Urls
26
+ def self.included(klass)
27
+ klass.helper_method :object_url, :object_path, :hash_for_object_url, :hash_for_object_path, :edit_object_url, :edit_object_path, :hash_for_edit_object_url,
28
+ :hash_for_edit_object_path, :new_object_url, :new_object_path, :hash_for_new_object_url, :hash_for_new_object_path, :collection_url, :collection_path,
29
+ :hash_for_collection_url, :hash_for_collection_path
30
+ end
31
+
27
32
  private
28
- # Used internally to provide the options to smart_url from Urligence.
29
- #
30
- def collection_url_parts(action = nil, url_params = {})
31
- [action] + contexts_url_parts + [route_name.to_s.pluralize.to_sym, url_params]
33
+ def object_url(*objects) # :doc:
34
+ smart_url *object_url_options(nil, objects)
35
+ end
36
+
37
+ def object_path(*objects)
38
+ smart_path *object_url_options(nil, objects)
39
+ end
40
+
41
+ def hash_for_object_url(*objects)
42
+ hash_for_smart_url *object_url_options(nil, objects)
43
+ end
44
+
45
+ def hash_for_object_path(*objects)
46
+ hash_for_smart_path *object_url_options(nil, objects)
47
+ end
48
+
49
+ def edit_object_url(*objects)
50
+ smart_url *object_url_options(:edit, objects)
51
+ end
52
+
53
+ def edit_object_path(*objects)
54
+ smart_path *object_url_options(:edit, objects)
32
55
  end
33
56
 
57
+ def hash_for_edit_object_url(*objects)
58
+ hash_for_smart_url *object_url_options(:edit, objects)
59
+ end
60
+
61
+ def hash_for_edit_object_path(*objects)
62
+ hash_for_smart_path *object_url_options(:edit, objects)
63
+ end
64
+
65
+ def new_object_url(url_params = {})
66
+ smart_url *new_object_url_options(url_params)
67
+ end
68
+
69
+ def new_object_path(url_params = {})
70
+ smart_path *new_object_url_options(url_params)
71
+ end
72
+
73
+ def hash_for_new_object_url(url_params = {})
74
+ hash_for_smart_url *new_object_url_options(url_params)
75
+ end
76
+
77
+ def hash_for_new_object_path(url_params = {})
78
+ hash_for_smart_path *new_object_url_options(url_params)
79
+ end
80
+
81
+ def collection_url(url_params = {})
82
+ smart_url *collection_url_options(url_params)
83
+ end
84
+
85
+ def collection_path(url_params = {})
86
+ smart_path *collection_url_options(url_params)
87
+ end
88
+
89
+ def hash_for_collection_url(url_params = {})
90
+ hash_for_smart_url *collection_url_options(url_params)
91
+ end
92
+
93
+ def hash_for_collection_path(url_params = {})
94
+ hash_for_smart_path *collection_url_options(url_params)
95
+ end
96
+
34
97
  # Used internally to provide the options to smart_url from Urligence.
35
98
  #
36
- def object_url_parts(action = nil, *alternate_object_or_params)
37
- alternate_object, url_params = identify_object_or_params(alternate_object_or_params)
38
- url_object = alternate_object
39
- url_object = object if url_object.nil? && object && !object.new_record?
40
- object_parts = url_object ?
41
- [route_name, url_object] :
42
- (action == :new || singleton? ? route_name : route_name.to_s.pluralize.to_sym)
43
- [action] + contexts_url_parts + [object_parts, url_params]
99
+ def collection_url_options(url_params = {})
100
+ namespaces + [parent_url_options, route_name.to_s.pluralize.to_sym, url_params]
44
101
  end
45
-
46
- def identify_object_or_params(object_or_params)
47
- obj = nil
48
- url_params = {}
49
- if object_or_params.size > 1
50
- url_params = object_or_params.last if object_or_params.last.is_a?(Hash)
51
- obj = object_or_params.first
52
- elsif object_or_params.first.is_a?(Hash)
53
- url_params = object_or_params.first
102
+
103
+ # Used internally to provide the options to smart_url from Urligence.
104
+ #
105
+ def object_url_options(action_prefix = nil, alternate_object_or_params = nil)
106
+ alternate_object = nil
107
+ url_params = nil
108
+ case alternate_object_or_params
109
+ when Array
110
+ url_params = alternate_object_or_params.last if alternate_object_or_params.last.is_a?(Hash)
111
+ alternate_object = alternate_object_or_params.first
112
+ when Hash
113
+ url_params = alternate_object_or_params
54
114
  else
55
- obj = object_or_params.first
115
+ alternate_object = alternate_object_or_params
56
116
  end
57
- [obj, url_params]
117
+
118
+ [action_prefix] + namespaces + [parent_url_options, [route_name.to_sym, alternate_object || (param ? object : nil)], url_params]
119
+ end
120
+
121
+ # Used internally to provide the options to smart_url from Urligence.
122
+ #
123
+ def new_object_url_options(url_params = {})
124
+ [:new] + namespaces + [parent_url_options, route_name.to_sym, url_params]
58
125
  end
59
126
  end
60
127
 
61
128
  module Reflection
62
129
  def self.included(klass)
63
- klass.helper_method :model_name, :collection, :object, :path_name, :route_name
130
+ klass.helper_method :model_name, :collection, :object
64
131
  end
65
132
 
66
133
  private
67
- def path_name
68
- return @path_name if defined?(@path_name)
69
- path_parts = request.path.split("/")
70
- path_parts.reverse.each do |path_part|
71
- next if path_part.blank?
72
- if model_name_from_path_part(path_part) == model_name
73
- return @path_name = path_part.to_sym
74
- end
75
- end
76
- @path_name = nil
77
- end
78
-
79
- def route_name
80
- return @route_name if defined?(@route_name)
81
- path_parts = request.path.split("/")
82
- path_parts.reverse.each do |path_part|
83
- next if path_part.blank?
84
- if model_name_from_path_part(path_part) == model_name
85
- return @route_name = route_name_from_path_part(path_part)
86
- end
87
- end
88
- @route_name = model_name
89
- end
90
-
91
134
  # Convenience method for the class level model_name method
92
135
  def model_name
93
- @model_name ||= self.class.model_name.to_sym
94
- end
95
-
96
- def model
97
- @model ||= model_name.to_s.camelize.constantize
136
+ self.class.model_name
98
137
  end
99
138
 
100
139
  # Convenience method for the class level object_name method
101
140
  def object_name
102
- @object_name ||= self.class.object_name.to_sym
141
+ self.class.object_name
142
+ end
143
+
144
+ # Convenience method for the class level route_name method
145
+ def route_name
146
+ self.class.route_name
147
+ end
148
+
149
+ # The current model for the resource.
150
+ def model # :doc:
151
+ model_name.to_s.camelize.constantize
103
152
  end
104
153
 
105
154
  # The collection for the resource.
106
155
  def collection # :doc:
107
- @collection ||= scope.all
156
+ end_of_association_chain.all
108
157
  end
109
158
 
110
159
  # The current paremter than contains the object identifier.
111
- def id # :doc:
112
- params[:id]
113
- end
114
-
115
- def id?
116
- params.key?(:id)
160
+ def param # :doc:
161
+ params[:id]
117
162
  end
118
163
 
119
164
  # The parameter hash that contains the object attributes.
120
- def attributes
121
- params[object_name]
122
- end
123
-
124
- def attributes?
125
- params.key?(object_name)
165
+ def object_params
166
+ params["#{object_name}"]
126
167
  end
127
-
168
+
128
169
  # The current member being used. If no param is present, it will look for
129
170
  # a current_#{object_name} method. For example, if you have a UsersController
130
171
  # and its a singleton controller, meaning no identifier is needed, this will
131
172
  # look for a current_user method. If this is not the behavioru you want, simply
132
173
  # overwrite this method.
133
174
  def object # :doc:
134
- @object ||= id? ? find_object : build_object
135
- end
136
-
137
- def build_object
138
- obj = scope.respond_to?(:build) ? scope.build : scope.new
139
- obj.attributes = attributes
140
- obj
141
- end
142
-
143
- def find_object
144
- scope.find(id)
175
+ return @object if defined?(@object)
176
+ if param.nil? && respond_to?("current_#{object_name}", true)
177
+ @object = send("current_#{object_name}")
178
+ else
179
+ @object = end_of_association_chain.find(param)
180
+ end
145
181
  end
146
182
  end
147
183
  end
@@ -7,13 +7,55 @@ module Resourcelogic
7
7
  end
8
8
 
9
9
  module Urls
10
+ def self.included(klass)
11
+ klass.helper_method :new_sibling_url, :new_sibling_path, :edit_sibling_url, :edit_sibling_path,
12
+ :sibling_url, :sibling_path, :sibling_collection_url, :sibling_collection_path
13
+ end
14
+
10
15
  private
11
- def sibling_url_parts(action = nil, sibling = nil, url_params = {})
12
- [action] + contexts_url_parts + [sibling.is_a?(Symbol) ? sibling : [sibling.class.name.underscore.to_sym, sibling], url_params]
16
+ def new_sibling_url(sibling_name, url_params = {})
17
+ smart_url *new_sibling_url_options(sibling_name, url_params)
18
+ end
19
+
20
+ def new_sibling_path(sibling_name, url_params = {})
21
+ smart_path *new_sibling_url_options(sibling_name, url_params)
22
+ end
23
+
24
+ def edit_sibling_url(sibling, url_params = {})
25
+ smart_url *sibling_url_options(sibling, :edit, url_params)
26
+ end
27
+
28
+ def edit_sibling_path(sibling, url_params = {})
29
+ smart_path *sibling_url_options(sibling, :edit, url_params)
30
+ end
31
+
32
+ def sibling_url(sibling, url_params = {})
33
+ smart_url *sibling_url_options(sibling, url_params)
34
+ end
35
+
36
+ def sibling_path(sibling, url_params = {})
37
+ smart_path *sibling_url_options(sibling, url_params)
38
+ end
39
+
40
+ def sibling_collection_url(sibling_name, url_params = {})
41
+ smart_url *sibling_collection_url_options(sibling_name, url_params)
42
+ end
43
+
44
+ def sibling_collection_path(sibling_name, url_params = {})
45
+ smart_path *sibling_collection_url_options(sibling_name, url_params)
46
+ end
47
+
48
+ def new_sibling_url_options(sibling_name, url_params = {})
49
+ [:new] + namespaces + [parent_url_options, sibling_name, url_params]
50
+ end
51
+
52
+ def sibling_url_options(sibling, *action_prefix_or_params)
53
+ action_prefix, url_params = identify_action_prefix_or_params(action_prefix_or_params)
54
+ [action_prefix] + namespaces + [parent_url_options, [sibling.class.name.underscore.to_sym, sibling], url_params]
13
55
  end
14
56
 
15
- def sibling_collection_url_parts(action = nil, sibling_name = nil, url_params = {})
16
- [action] + contexts_url_parts + [sibling_name, url_params]
57
+ def sibling_collection_url_options(sibling_name, url_params = {})
58
+ namespaces + [parent_url_options, sibling_name, url_params]
17
59
  end
18
60
  end
19
61
  end
@@ -4,52 +4,70 @@ module Resourcelogic
4
4
  module Singleton
5
5
  def self.included(klass)
6
6
  klass.class_eval do
7
- add_acts_as_resource_module(Methods)
7
+ extend Config
8
8
  end
9
9
  end
10
10
 
11
- module Methods
12
- def object
13
- return @object if defined?(@object)
14
-
15
- if singleton?
16
- if !parent? && respond_to?("current_#{model_name}", true)
17
- @object = send("current_#{model_name}")
18
- elsif parent? && parent_object.send(model_name)
19
- @object = parent_object.send(model_name)
20
- else
21
- super
22
- end
23
- else
24
- super
25
- end
11
+ module Config
12
+ def singleton(value = nil)
13
+ include Methods if value == true
14
+ config(:singleton, value)
26
15
  end
27
16
 
28
- def build_object
29
- if singleton? && parent?
30
- scope.send("build_#{model_name}")
31
- else
32
- super
33
- end
17
+ def singleton?
18
+ singleton == true
34
19
  end
35
-
36
- def scope
37
- if singleton? && parent?
38
- parent_object
39
- else
40
- super
20
+ end
21
+
22
+ module Methods
23
+ def self.included(klass)
24
+ klass.class_eval do
25
+ methods_to_undefine = [:index, :collection, :load_collection, :collection_url,
26
+ :collection_path, :hash_for_collection_url, :hash_for_collection_path]
27
+ methods_to_undefine.each { |method| undef_method(method) if method_defined?(method) }
41
28
  end
42
29
  end
43
30
 
44
- # Route alises can only be used for singleton, like account => user. Otherwise the urligence wont work because there is no account model.
45
- def object_url_parts(action = nil, *alternate_object_or_params)
46
- singleton? ? ([action] + contexts_url_parts + [route_name]) : super
47
- end
48
-
49
- # Override me with true to make singleton
50
- def singleton?
51
- false
52
- end
31
+ private
32
+ # Used to fetch the current object in a singleton controller.
33
+ #
34
+ # By defult this method is able to fetch the current object for resources nested with the :has_one association only. (i.e. /users/1/image # => @user.image)
35
+ # In other cases you should override this method and provide your custom code to fetch a singleton resource object, like using a session hash.
36
+ #
37
+ # class AccountsController < ResourceController::Singleton
38
+ # private
39
+ # def object
40
+ # @object ||= Account.find(session[:account_id])
41
+ # end
42
+ # end
43
+ #
44
+ def object
45
+ @object ||= parent? ? end_of_association_chain : nil
46
+ end
47
+
48
+ # Returns the :has_one association proxy of the parent. (i.e. /users/1/image # => @user.image)
49
+ #
50
+ def parent_association
51
+ @parent_association ||= parent_object.send(model_name.to_sym)
52
+ end
53
+
54
+ # Used internally to provide the options to smart_url in a singleton controller.
55
+ #
56
+ def object_url_options(action_prefix = nil, alternate_object = nil)
57
+ [action_prefix] + namespaces + [parent_url_options, route_name.to_sym]
58
+ end
59
+
60
+ # Builds the object, but doesn't save it, during the new, and create action.
61
+ #
62
+ def build_object
63
+ @object ||= singleton_build_object_base.send parent? ? "build_#{model_name}".to_sym : :new, object_params
64
+ end
65
+
66
+ # Singleton controllers don't build off of association proxy, so we can't use end_of_association_chain here
67
+ #
68
+ def singleton_build_object_base
69
+ parent? ? parent_object : model
70
+ end
53
71
  end
54
72
  end
55
73
  end