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.
@@ -3,13 +3,11 @@ module Resourcelogic # :nodoc:
3
3
  def self.included(klass)
4
4
  klass.class_eval do
5
5
  extend ClassMethods
6
- include InstanceMethods
7
6
  end
8
7
  end
9
8
 
10
9
  module ClassMethods
11
10
  def acts_as_resource(&block)
12
- resourceful(true)
13
11
  yield self if block_given?
14
12
  acts_as_resource_modules.each { |mod| include mod }
15
13
  init_default_actions
@@ -67,21 +65,13 @@ module Resourcelogic # :nodoc:
67
65
  acts_as_resource_modules
68
66
  end
69
67
 
70
- def resourceful(value = nil)
71
- rw_config(:resourceful, value, false)
72
- end
73
-
74
- def resourceful?
75
- resourceful == true
76
- end
77
-
78
68
  private
79
69
  def acts_as_resource_modules
80
70
  key = :acts_as_resource_modules
81
71
  inheritable_attributes.include?(key) ? read_inheritable_attribute(key) : []
82
72
  end
83
73
 
84
- def rw_config(key, value, default_value = nil, read_value = nil)
74
+ def config(key, value, default_value = nil, read_value = nil)
85
75
  if value == read_value
86
76
  inheritable_attributes.include?(key) ? read_inheritable_attribute(key) : default_value
87
77
  else
@@ -89,21 +79,6 @@ module Resourcelogic # :nodoc:
89
79
  end
90
80
  end
91
81
  end
92
-
93
- module InstanceMethods
94
- def self.included(klass)
95
- klass.helper_method :resourceful?, :section
96
- end
97
-
98
- def resourceful?
99
- self.class.resourceful?
100
- end
101
-
102
- def section
103
- section = request.path.split("/")[1]
104
- section && section.to_sym
105
- end
106
- end
107
82
  end
108
83
  end
109
84
 
@@ -115,16 +90,11 @@ if defined?(::ActionController)
115
90
  include Resourcelogic::Actions
116
91
  include Resourcelogic::Child
117
92
  include Resourcelogic::Context
118
- include Resourcelogic::Scope
93
+ include Resourcelogic::Parent
119
94
  include Resourcelogic::Self
120
95
  include Resourcelogic::Sibling
121
- include Resourcelogic::SubViews
96
+ include Resourcelogic::Singleton
122
97
  include Resourcelogic::Urligence
123
-
124
- # Need to be loaded last to override methods
125
- include Resourcelogic::Parent
126
- include Resourcelogic::Aliases
127
- include Resourcelogic::Singleton
128
98
  end
129
99
  end
130
100
  end
@@ -7,49 +7,89 @@ 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
+
10
15
  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
+
11
36
  # The following should work
12
37
  #
13
38
  # child_path(obj)
14
39
  # child_path(obj, :id => 2) # where obj is then replaced by the obj with id 2
15
40
  # child_path(:child_name, :id => 2) # where this is a literal build of the url
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]
41
+ def child_path(child, url_params = {})
42
+ smart_path *child_url_options(child, url_params)
18
43
  end
19
44
 
20
- def child_collection_url_parts(action = nil, child_name = nil, url_params = {})
21
- child_base_parts(action, url_params) + [child_name, url_params]
45
+ def child_collection_url(child_name, url_params = {})
46
+ smart_url *child_collection_url_options(child_name, url_params)
22
47
  end
23
48
 
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
49
+ def child_collection_path(child_name, url_params = {})
50
+ smart_path *child_collection_url_options(child_name, url_params)
51
+ end
52
+
53
+ def new_child_url_options(child_name, url_params = {})
54
+ object_url_options(:new) + [child_name, url_params]
55
+ end
56
+
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
53
93
  end
54
94
  end
55
95
  end
@@ -4,48 +4,85 @@ module Resourcelogic
4
4
  module Context
5
5
  def self.included(klass)
6
6
  klass.class_eval do
7
+ extend Config
7
8
  add_acts_as_resource_module(Methods)
8
9
  end
9
10
  end
10
11
 
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
+
11
22
  module Methods
12
23
  def self.included(klass)
13
- klass.helper_method :context, :contexts, :contexts_url_parts
14
- klass.hide_action :context, :contexts
24
+ klass.helper_method :context, :contexts, :contextual_views, :contextual_views?, :context_template_name
15
25
  end
16
26
 
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)
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))
29
30
  end
30
- @contexts
31
- end
32
31
 
33
- private
34
- def contexts_url_parts
35
- return @contexts_url_parts if @contexts_url_parts
32
+ # Returns all of the current namespaces of the current controller, symbolized, in array form.
33
+ def contexts
34
+ return @contexts if @contexts
36
35
  path_parts = request.path.split("/")
37
36
  path_parts.shift
38
- @contexts_url_parts = []
37
+ @contexts = []
39
38
  path_parts.each_with_index do |part, index|
40
- break if model_name_from_path_part(part.split(".").first) == model_name
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)
41
41
  if part.to_i > 0
42
- @contexts_url_parts << [route_name_from_path_part(@contexts_url_parts.pop), part.to_i]
42
+ @contexts << [@contexts.pop.to_s.singularize.to_sym, part]
43
43
  else
44
- @contexts_url_parts << part.underscore.to_sym
44
+ @contexts << part.underscore.to_sym
45
45
  end
46
46
  end
47
- @contexts_url_parts
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
48
71
  end
49
72
  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
50
87
  end
51
88
  end
@@ -17,125 +17,157 @@ 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
24
20
  end
25
21
 
26
22
  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
+
27
28
  private
28
- def parent_url_parts(action = nil, url_params = {})
29
- [action] + contexts_url_parts + [url_params]
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])
30
47
  end
31
48
 
32
- def parent_collection_url_parts(*args)
33
- parent_url_parts(*args)
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
34
68
  end
35
69
  end
36
70
 
37
71
  module Reflection
38
72
  def self.included(klass)
39
- klass.class_eval do
40
- helper_method :parent?, :parent_model_name, :parent_object
41
- before_filter :require_parent
42
- end
73
+ klass.helper_method :parent?, :parent_model_name, :parent_object
43
74
  end
44
75
 
45
76
  private
46
77
  def belongs_to
47
78
  self.class.belongs_to
48
79
  end
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
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)
60
85
  end
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
86
+
87
+ def parent_alias
88
+ return @parent_alias if @parent_alias
89
+ parent_from_params? || parent_from_request?
90
+ @parent_alias
72
91
  end
73
-
92
+
74
93
  # Returns the type of the current parent
75
94
  #
76
95
  def parent_model_name
77
- return @parent_model_name if defined?(@parent_model_name)
78
- parent_from_path?
96
+ return @parent_model_name if @parent_model_name
97
+ parent_from_params? || parent_from_request?
79
98
  @parent_model_name
80
99
  end
81
-
82
- def parent_model
83
- @parent_model ||= parent_model_name.to_s.camelize.constantize
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
84
113
  end
85
-
114
+
86
115
  # Returns the type of the current parent extracted form a request path
87
- #
88
- def parent_from_path?
89
- return @parent_from_path if defined?(@parent_from_path)
116
+ #
117
+ def parent_from_request?
118
+ return @parent_from_request if defined?(@parent_from_request)
90
119
  belongs_to.each do |model_name, options|
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
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
98
124
  end
99
125
  end
100
- @parent_from_path = false
126
+ @parent_from_request = false
101
127
  end
102
-
128
+
103
129
  # Returns true/false based on whether or not a parent is present.
104
130
  #
105
131
  def parent?
106
132
  !parent_model_name.nil?
107
133
  end
108
-
134
+
109
135
  # Returns true/false based on whether or not a parent is a singleton.
110
- #
136
+ #
111
137
  def parent_singleton?
112
- parent? && parent_id.nil?
138
+ !parent_from_params?
113
139
  end
114
-
140
+
115
141
  # Returns the current parent param, if there is a parent. (i.e. params[:post_id])
116
- def parent_id
117
- params["#{parent_route_name}_id".to_sym]
142
+ def parent_param
143
+ params["#{parent_model_name}_id".to_sym]
118
144
  end
119
-
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
+
120
152
  # Returns the current parent object if a parent object is present.
121
153
  #
122
- def parent_object(reload = false)
123
- return @parent_object if !reload && defined?(@parent_object)
154
+ def parent_object
155
+ return @parent_object if defined?(@parent_object)
124
156
  if parent?
125
157
  if parent_singleton? && respond_to?("current_#{parent_model_name}", true)
126
158
  @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)
129
159
  else
130
- @parent_object = parent_scope.find(parent_id)
160
+ @parent_object = parent_model.find(parent_param)
131
161
  end
132
162
  else
133
163
  @parent_object = nil
134
164
  end
135
165
  end
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
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
139
171
  end
140
172
  end
141
173
  end