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.
@@ -1,60 +1,57 @@
1
1
  module Resourcelogic
2
2
  module Urligence
3
- def self.included(klass)
4
- klass.helper_method :smart_url, :smart_path, :hash_for_smart_url, :hash_for_smart_path, :method_missing
3
+ def smart_url(*objects)
4
+ url_params = objects.extract_options!
5
+ objects.push(:url)
6
+ objects.push(url_params)
7
+ urligence(*objects)
5
8
  end
6
-
7
- def smart_url(*url_parts)
8
- url_params = url_parts.extract_options!
9
- url_parts.push(:url)
10
- url_parts.push(url_params)
11
- urligence(*url_parts)
9
+
10
+ def smart_path(*objects)
11
+ url_params = objects.extract_options!
12
+ objects.push(:path)
13
+ objects.push(url_params)
14
+ urligence(*objects)
12
15
  end
13
-
14
- def smart_path(*url_parts)
15
- url_params = url_parts.extract_options!
16
- url_parts.push(:path)
17
- url_parts.push(url_params)
18
- urligence(*url_parts)
16
+
17
+ def hash_for_smart_url(*objects)
18
+ urligence(*objects.unshift(:hash_for).push(:url).push({:type => :hash}))
19
19
  end
20
-
21
- def hash_for_smart_url(*url_parts)
22
- urligence(*url_parts.unshift(:hash_for).push(:url).push({:type => :hash}))
20
+
21
+ def hash_for_smart_path(*objects)
22
+ urligence(*objects.unshift(:hash_for).push(:path).push({:type => :hash}))
23
23
  end
24
+
25
+ def urligence(*objects)
26
+ objects = cleanup_url_objects(objects)
27
+ url_fragments = extract_url_fragments(objects)
28
+ url_objects = extract_url_objects(objects)
24
29
 
25
- def hash_for_smart_path(*url_parts)
26
- urligence(*url_parts.unshift(:hash_for).push(:path).push({:type => :hash}))
27
- end
28
-
29
- private
30
- def urligence(*url_parts)
31
- url_parts = cleanup_url_parts(url_parts)
32
- method_name_fragments = extract_method_name_fragments(url_parts)
33
- method_arguments = extract_method_arguments(url_parts)
34
-
35
- if url_parts.first != :hash_for
36
- send method_name_fragments.join("_"), *method_arguments
30
+ begin
31
+ if objects.first != :hash_for
32
+ send url_fragments.join("_"), *url_objects
37
33
  else
38
- url_params = method_arguments.extract_options!
34
+ url_params = url_objects.extract_options!
39
35
  params = {}
40
- method_arguments.each_with_index do |obj, i|
41
- key = i == (method_arguments.size - 1) ?
42
- :id :
43
- (obj.is_a?(Array) ? "#{obj.first}_id".to_sym : "#{obj.class.name.underscore}_id".to_sym)
36
+ url_objects.each_with_index do |obj, i|
37
+ key = i == (url_objects.size - 1) ? :id : (obj.is_a?(Array) ? "#{obj.first}_id".to_sym : "#{obj.class.name.underscore}_id".to_sym)
44
38
  params.merge!((obj.is_a?(Array)) ? {key => obj[1].to_param} : {key => obj.to_param})
45
39
  end
46
-
40
+
47
41
  params.merge!(url_params)
48
- send method_name_fragments.join("_"), params
42
+ send url_fragments.join("_"), params
49
43
  end
44
+ rescue NoMethodError
45
+ raise objects.inspect
50
46
  end
51
-
47
+ end
48
+
49
+ private
52
50
  # The point of this method is to replace any object if a url param is passed. For example:
53
51
  #
54
- # [:admin, [:user, user_object], {:user_id => 4}]
52
+ # [:user, user_object], {:user_id => 4}
55
53
  #
56
- # The "user_object" should be replaced by user with id 4, since we are explicitly saying we want to use User.find(4).
57
- # The last part is the url_params.
54
+ # The "user_object" should be replaced by user with id 4.
58
55
  #
59
56
  # This also pluralizes path names if the obj is nil. Example:
60
57
  #
@@ -70,35 +67,31 @@ module Resourcelogic
70
67
  # payments/credit_cards
71
68
  #
72
69
  # You can manage and select a credit card from the credit cards resource but a payment object
73
- # is not needed. In a sense you are just creating a "payments" context.
74
- def cleanup_url_parts(url_parts)
75
- url_parts = url_parts.compact
76
- url_params = url_parts.last.is_a?(Hash) ? url_parts.last : {}
77
- new_url_parts = []
78
-
79
- url_parts.each do |object|
70
+ # is not needed.
71
+ def cleanup_url_objects(objects)
72
+ objects = objects.compact
73
+ url_params = objects.last.is_a?(Hash) ? objects.last : {}
74
+ non_symbol_object_total = objects.select { |object| !object.is_a?(Symbol) }.size - 1
75
+ non_symbol_object_count = 0
76
+ new_objects = []
77
+ objects.each do |object|
78
+ non_symbol_object_count += 1 if !object.is_a?(Symbol)
80
79
  if !object.is_a?(Array)
81
- # It's not an array, just copy it over
82
- new_url_parts << object
80
+ new_objects << object
83
81
  else
84
- # Let's try to
85
82
  klass = object.first.to_s.camelize.constantize rescue nil
86
- #klass_name = klass ? klass.name.underscore : nil
87
- params_key = "#{object.first}_id".to_sym
88
- obj = if url_params.key?(params_key)
89
- (!klass && url_params[params_key]) || (url_params[params_key] && klass.find(url_params.delete(params_key)))
90
- else
91
- object[1]
92
- end
93
- new_url_parts << [object.first, obj]
94
- #new_url_parts << (obj.nil? ? object.first.to_s.pluralize.to_sym : [object.first, obj])
83
+ klass_name = klass ? klass.name.underscore : nil
84
+ key = (non_symbol_object_count == non_symbol_object_total) ? :id : "#{object.first}_id".to_sym
85
+ obj = (url_params.key?(key) ? ((!klass && url_params[key]) || (url_params[key] && klass.find(url_params.delete(key)))) : object[1])
86
+ new_objects << (obj.nil? ? object.first.to_s.pluralize.to_sym : [object.first, obj])
95
87
  end
96
88
  end
97
- new_url_parts
89
+ new_objects
98
90
  end
99
-
100
- def extract_method_name_fragments(url_parts)
101
- fragments = url_parts.collect do |obj|
91
+
92
+
93
+ def extract_url_fragments(objects)
94
+ fragments = objects.collect do |obj|
102
95
  if obj.is_a?(Symbol)
103
96
  obj
104
97
  elsif obj.is_a?(Array)
@@ -109,20 +102,9 @@ module Resourcelogic
109
102
  end
110
103
  fragments.compact
111
104
  end
112
-
113
- def extract_method_arguments(url_parts)
114
- url_parts.flatten.select { |obj| !obj.is_a?(Symbol) }
115
- end
116
-
117
- def method_missing(method, *args, &block)
118
- if method.to_s =~ /^((.*)_)?(child_collection|parent_collection|sibling|sibling_collection)_(path|url)$/ || method.to_s =~ /^((.*)_)?(child|collection|object|parent)_(path|url)$/
119
- action = $2.blank? ? nil : $2.to_sym
120
- target = $3
121
- url_type = $4
122
- send("smart_#{url_type}", *send("#{target}_url_parts", action, *args))
123
- else
124
- super
125
- end
105
+
106
+ def extract_url_objects(objects)
107
+ objects.flatten.select { |obj| !obj.is_a?(Symbol) }
126
108
  end
127
109
  end
128
110
  end
@@ -0,0 +1,51 @@
1
+ module Resourcelogic # :nodoc:
2
+ # A class for describing the current version of a library. The version
3
+ # consists of three parts: the +major+ number, the +minor+ number, and the
4
+ # +tiny+ (or +patch+) number.
5
+ class Version
6
+ include Comparable
7
+
8
+ # A convenience method for instantiating a new Version instance with the
9
+ # given +major+, +minor+, and +tiny+ components.
10
+ def self.[](major, minor, tiny)
11
+ new(major, minor, tiny)
12
+ end
13
+
14
+ attr_reader :major, :minor, :tiny
15
+
16
+ # Create a new Version object with the given components.
17
+ def initialize(major, minor, tiny)
18
+ @major, @minor, @tiny = major, minor, tiny
19
+ end
20
+
21
+ # Compare this version to the given +version+ object.
22
+ def <=>(version)
23
+ to_i <=> version.to_i
24
+ end
25
+
26
+ # Converts this version object to a string, where each of the three
27
+ # version components are joined by the '.' character. E.g., 2.0.0.
28
+ def to_s
29
+ @to_s ||= [@major, @minor, @tiny].join(".")
30
+ end
31
+
32
+ # Converts this version to a canonical integer that may be compared
33
+ # against other version objects.
34
+ def to_i
35
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
36
+ end
37
+
38
+ def to_a
39
+ [@major, @minor, @tiny]
40
+ end
41
+
42
+ MAJOR = 0
43
+ MINOR = 9
44
+ TINY = 0
45
+
46
+ # The current version as a Version instance
47
+ CURRENT = new(MAJOR, MINOR, TINY)
48
+ # The current version as a String
49
+ STRING = CURRENT.to_s
50
+ end
51
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resourcelogic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Johnson of Binary Logic
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-28 00:00:00 -04:00
12
+ date: 2009-04-02 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,49 +22,54 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0"
24
24
  version:
25
- description:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.11.0
34
+ version:
35
+ description: Making an API a byproduct of good design.
26
36
  email: bjohnson@binarylogic.com
27
37
  executables: []
28
38
 
29
39
  extensions: []
30
40
 
31
41
  extra_rdoc_files:
32
- - LICENSE
42
+ - Manifest.txt
43
+ - CHANGELOG.rdoc
33
44
  - README.rdoc
34
45
  files:
35
- - .gitignore
36
46
  - CHANGELOG.rdoc
37
- - LICENSE
47
+ - MIT-LICENSE
48
+ - Manifest.txt
38
49
  - README.rdoc
39
50
  - Rakefile
40
- - VERSION.yml
41
51
  - init.rb
42
52
  - lib/resourcelogic.rb
43
53
  - lib/resourcelogic/accessors.rb
44
54
  - lib/resourcelogic/action_options.rb
45
55
  - lib/resourcelogic/actions.rb
46
- - lib/resourcelogic/aliases.rb
47
56
  - lib/resourcelogic/base.rb
48
57
  - lib/resourcelogic/child.rb
49
58
  - lib/resourcelogic/context.rb
50
- - lib/resourcelogic/context_options.rb
51
59
  - lib/resourcelogic/failable_action_options.rb
52
60
  - lib/resourcelogic/parent.rb
53
61
  - lib/resourcelogic/response_collector.rb
54
- - lib/resourcelogic/scope.rb
55
62
  - lib/resourcelogic/self.rb
56
63
  - lib/resourcelogic/sibling.rb
57
64
  - lib/resourcelogic/singleton.rb
58
- - lib/resourcelogic/sub_views.rb
59
65
  - lib/resourcelogic/urligence.rb
60
- - resourcelogic.gemspec
66
+ - lib/resourcelogic/version.rb
61
67
  has_rdoc: true
62
68
  homepage: http://github.com/binarylogic/resourcelogic
63
- licenses: []
64
-
65
69
  post_install_message:
66
70
  rdoc_options:
67
- - --charset=UTF-8
71
+ - --main
72
+ - README.rdoc
68
73
  require_paths:
69
74
  - lib
70
75
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -82,9 +87,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
87
  requirements: []
83
88
 
84
89
  rubyforge_project: resourcelogic
85
- rubygems_version: 1.3.4
90
+ rubygems_version: 1.3.1
86
91
  signing_key:
87
- specification_version: 3
88
- summary: Removes the need to namespace controllers by adding context and relative url functions among other things.
92
+ specification_version: 2
93
+ summary: Making an API a byproduct of good design.
89
94
  test_files: []
90
95
 
data/.gitignore DELETED
@@ -1,7 +0,0 @@
1
- .DS_Store
2
- *.log
3
- *.sqlite3
4
- pkg/*
5
- coverage/*
6
- doc/*
7
- benchmarks/*
@@ -1,4 +0,0 @@
1
- ---
2
- :patch: 12
3
- :major: 0
4
- :minor: 0
@@ -1,134 +0,0 @@
1
- module Resourcelogic
2
- # This module let's you define various aliases for your controller. For example,
3
- # lets say you have the following routes:
4
- #
5
- # /account/addresses => UsersController
6
- # /admin/users/5/addresses => UsersController
7
- #
8
- # Here is how your AddressesController would look:
9
- #
10
- # class AddressesController < ResourceController
11
- # belongs_to :user
12
- # end
13
- #
14
- # The problem is that sometimes the parent object is called user, sometimes its
15
- # called account. So the solution is to do:
16
- #
17
- # class ResourceController < ApplicationController
18
- # route_alias :account, :user
19
- # end
20
- #
21
- # Now ResourceLogic knows that when it see account in the URL it will know the grab
22
- # the User model.
23
- #
24
- # Now I know an alternative could be to do somethig like:
25
- #
26
- # belongs_to :user, :alias => :account
27
- #
28
- # The above presents a problem. Take the following URL:
29
- #
30
- # /productos/1/pictures/4/comments
31
- #
32
- # In order for Resourcelogic to do its magic relative URLs, it needs to know what
33
- # model "productos" should be using. Which should be the Product model, yet we
34
- # can't define that in the CommentsController because it's 2 levels above, and we
35
- # only specify the parent.
36
- #
37
- # Now a lot of people say you should never nest more than 2 levels deep, and this
38
- # is absolutely true 95% of the time. But what if I want to link back to the parent
39
- # object from the comments controller and preserve it's context? In order to do
40
- # this I have to go 3 levels deep, because maybe context for the PicturesController
41
- # is really important / required. The only way to preserve context is with the URL.
42
- #
43
- # Sorry for rambling, this documentation is really more of an internal note for me
44
- # and to hopefully clarify why I took this approach.
45
- module Aliases
46
- def self.included(klass)
47
- klass.class_eval do
48
- extend Config
49
- include InstanceMethods
50
- end
51
- end
52
-
53
- module Config
54
- def path_alias(alias_name, model_name)
55
- current_aliases = path_aliases
56
- model_name = model_name.to_sym
57
- current_aliases[model_name] ||= []
58
- current_aliases[model_name] << alias_name.to_sym
59
- write_inheritable_attribute(:path_aliases, current_aliases)
60
- end
61
-
62
- def path_aliases
63
- read_inheritable_attribute(:path_aliases) || {}
64
- end
65
-
66
- def route_alias(alias_name, model_name)
67
- current_aliases = route_aliases
68
- model_name = model_name.to_sym
69
- current_aliases[model_name] ||= []
70
- current_aliases[model_name] << alias_name.to_sym
71
- write_inheritable_attribute(:route_aliases, current_aliases)
72
- end
73
-
74
- def route_aliases
75
- read_inheritable_attribute(:route_aliases) || {}
76
- end
77
- end
78
-
79
- module InstanceMethods
80
- private
81
- def model_name_from_route_alias(alias_name)
82
- route_aliases.each do |model_name, aliases|
83
- return model_name if aliases.include?(alias_name.to_sym)
84
- end
85
- nil
86
- end
87
-
88
- def route_aliases
89
- self.class.route_aliases
90
- end
91
-
92
- def model_name_from_path_alias(alias_name)
93
- path_aliases.each do |model_name, aliases|
94
- return model_name if aliases.include?(alias_name.to_sym)
95
- end
96
- nil
97
- end
98
-
99
- def path_aliases
100
- self.class.path_aliases
101
- end
102
-
103
- def possible_model_names(model_name)
104
- [model_name] + (route_aliases[model_name] || []) + (path_aliases[model_name] || [])
105
- end
106
-
107
- # The point of this method is to determine what the part of a url is really referring to.
108
- # For example, let's say you did this:
109
- #
110
- # map.resources :users, :as => :accounts
111
- #
112
- # Resource logic looks at the request.path. It's going to see "accounts" in the urls. How
113
- # is it to know that by "accounts" you are referring to the "users" resource. That's the
114
- # point of this method, to say "hey, accounts is mapped to users".
115
- def model_name_from_path_part(part)
116
- part = part.to_s.singularize
117
- model_name_from_route_alias(part) || model_name_from_path_alias(part) || part.to_sym
118
- end
119
-
120
- # The point of this method is to determine the name used in the route method. For example,
121
- # let's say you did this:
122
- #
123
- # map.resources :accounts, :controller => "users"
124
- #
125
- # You would want to use "account" in your path and url helper, not "user".
126
- def route_name_from_path_part(part)
127
- part = part.to_s.singularize
128
- model_name = model_name_from_path_alias(part)
129
- return model_name if model_name
130
- part.to_sym
131
- end
132
- end
133
- end
134
- end