resourcelogic 0.0.12 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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