resource_mapper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,67 @@
1
+ # Nested and Polymorphic Resource Helpers
2
+ #
3
+ module ResourceMapper
4
+ module Helpers
5
+ module Nested
6
+ protected
7
+ # Returns the relevant association proxy of the parent. (i.e. /posts/1/comments # => @post.comments)
8
+ #
9
+ def parent_association
10
+ @parent_association ||= parent_object.send(model_name.to_s.pluralize.to_sym)
11
+ end
12
+
13
+ # Returns the type of the current parent
14
+ #
15
+ def parent_type
16
+ @parent_type ||= parent_type_from_params || parent_type_from_request
17
+ end
18
+
19
+ # Returns the type of the current parent extracted from params
20
+ #
21
+ def parent_type_from_params
22
+ [*belongs_to].find { |parent| !params["#{parent}_id".to_sym].nil? }
23
+ end
24
+
25
+ # Returns the type of the current parent extracted form a request path
26
+ #
27
+ def parent_type_from_request
28
+ [*belongs_to].find { |parent| request.path.split('/').include? parent.to_s }
29
+ end
30
+
31
+ # Returns true/false based on whether or not a parent is present.
32
+ #
33
+ def parent?
34
+ !parent_type.nil?
35
+ end
36
+
37
+ # Returns true/false based on whether or not a parent is a singleton.
38
+ #
39
+ def parent_singleton?
40
+ !parent_type_from_request.nil? && parent_type_from_params.nil?
41
+ end
42
+
43
+ # Returns the current parent param, if there is a parent. (i.e. params[:post_id])
44
+ def parent_param
45
+ params["#{parent_type}_id".to_sym]
46
+ end
47
+
48
+ # Like the model method, but for a parent relationship.
49
+ #
50
+ def parent_model
51
+ parent_type.to_s.camelize.constantize
52
+ end
53
+
54
+ # Returns the current parent object if a parent object is present.
55
+ #
56
+ def parent_object
57
+ parent? && !parent_singleton? ? parent_model.find(parent_param) : nil
58
+ end
59
+
60
+ # If there is a parent, returns the relevant association proxy. Otherwise returns model.
61
+ #
62
+ def end_of_association_chain
63
+ parent? ? parent_association : model
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,27 @@
1
+ module ResourceMapper
2
+ class ResponseCollector
3
+
4
+ attr_reader :responses
5
+
6
+ delegate :clear, :to => :responses
7
+
8
+ def initialize
9
+ @responses = []
10
+ end
11
+
12
+ def method_missing(method_name, &block)
13
+ @responses.delete self[method_name]
14
+ @responses << [method_name, block || nil]
15
+ end
16
+
17
+ def [](symbol)
18
+ @responses.find { |method, block| method == symbol }
19
+ end
20
+
21
+ def dup
22
+ returning ResponseCollector.new do |duplicate|
23
+ duplicate.instance_variable_set(:@responses, responses.dup)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,104 @@
1
+ require 'sinatra/base'
2
+ require 'active_support/inflector'
3
+
4
+ module Sinatra
5
+ module Resource
6
+ DEFAULT_FORMAT = :json
7
+
8
+ def get_with_formats(path, options = {}, &block)
9
+ route_method_for_formats :get, path, options, &block
10
+ end
11
+
12
+ def post_with_formats(path, options = {}, &block)
13
+ route_method_for_formats :post, path, options, &block
14
+ end
15
+
16
+ def put_with_formats(path, options = {}, &block)
17
+ route_method_for_formats :put, path, options, &block
18
+ end
19
+
20
+ def delete_with_formats(path, options = {}, &block)
21
+ route_method_for_formats :delete, path, options, &block
22
+ end
23
+
24
+ def resource(model, options = {}, &block)
25
+ klass = Class.new
26
+
27
+ klass.class_eval <<-"end_eval", __FILE__, __LINE__
28
+ attr_accessor :app, :wants
29
+ delegate :request, :response, :params, :session, :to => :app
30
+
31
+ def self.controller_name
32
+ "#{model.to_s.demodulize.downcase.pluralize}"
33
+ end
34
+
35
+ def self.model_name
36
+ "#{model.to_s.demodulize.downcase}"
37
+ end
38
+
39
+ def self.model
40
+ model
41
+ end
42
+
43
+ def respond_to
44
+ yield wants
45
+ end
46
+
47
+ include ResourceMapper::Controller
48
+ end_eval
49
+ klass.class_eval &block if block_given?
50
+ setup_routes(model, klass)
51
+ end
52
+
53
+ private
54
+ def route_method_for_formats(method, path, options = {}, &block)
55
+ handler = method_with_format_handler(&block)
56
+ self.method(method).call "#{path}.:format", options, &handler
57
+ self.method(method).call "#{path}", options, &handler
58
+ end
59
+
60
+ def method_with_format_handler(&block)
61
+ lambda do
62
+ wants = {}
63
+ format = (params[:format] || DEFAULT_FORMAT).to_sym
64
+ def wants.method_missing(type, *args, &handler)
65
+ self[type] = handler
66
+ end
67
+
68
+ block.bind(self).call(wants)
69
+ halt 404 if wants[format].nil?
70
+
71
+ wants[format].call
72
+ end
73
+ end
74
+
75
+ def route_handler(resource_klass, method)
76
+ lambda do |wants|
77
+ resource = resource_klass.new
78
+ resource.app = self
79
+ resource.wants = wants
80
+ resource.method(method).call
81
+ end
82
+ end
83
+
84
+ def setup_routes(model, resource)
85
+ name = model.to_s.demodulize.downcase
86
+
87
+ get_with_formats "/#{name.pluralize}", {}, &route_handler(resource, :index) unless resource.instance_methods.index(:index).nil?
88
+ get_with_formats "/#{name}/:id", {}, &route_handler(resource, :show) unless resource.instance_methods.index(:show).nil?
89
+ post_with_formats "/#{name}", {}, &route_handler(resource, :create) unless resource.instance_methods.index(:create).nil?
90
+ put_with_formats "/#{name}/:id", {}, &route_handler(resource, :update) unless resource.instance_methods.index(:update).nil?
91
+ delete_with_formats "/#{name}/:id", {}, &route_handler(resource, :destroy) unless resource.instance_methods.index(:destroy).nil?
92
+ end
93
+ end
94
+
95
+ class Base
96
+ class << self
97
+ alias_method :orig_helpers, :helpers
98
+ def helpers(*extensions, &block)
99
+ ResourceMapper::Helpers.class_eval(&block) if block_given?
100
+ orig_helpers *extensions, &block
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,80 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{resource_mapper}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Adam Elliot"]
12
+ s.date = %q{2010-06-24}
13
+ s.description = %q{Creates a resource for a model in sinatra}
14
+ s.email = %q{adam@adamelliot.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".autotest",
21
+ ".document",
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "examples/example_helper.rb",
28
+ "examples/lib/sinatra/resource_example.rb",
29
+ "examples/models.rb",
30
+ "lib/resource_mapper.rb",
31
+ "lib/resource_mapper/accessors.rb",
32
+ "lib/resource_mapper/action_options.rb",
33
+ "lib/resource_mapper/actions.rb",
34
+ "lib/resource_mapper/class_methods.rb",
35
+ "lib/resource_mapper/controller.rb",
36
+ "lib/resource_mapper/failable_action_options.rb",
37
+ "lib/resource_mapper/helpers/current_objects.rb",
38
+ "lib/resource_mapper/helpers/internal.rb",
39
+ "lib/resource_mapper/helpers/nested.rb",
40
+ "lib/resource_mapper/response_collector.rb",
41
+ "lib/sinatra/resource.rb",
42
+ "resource_mapper.gemspec"
43
+ ]
44
+ s.homepage = %q{http://github.com/adamelliot/resource_mapper}
45
+ s.rdoc_options = ["--charset=UTF-8"]
46
+ s.require_paths = ["lib"]
47
+ s.rubygems_version = %q{1.3.7}
48
+ s.summary = %q{A resource_controller derivate that brings similar functionality to Sinatra, but provides a simple way to create restful APIs}
49
+ s.test_files = [
50
+ "examples/example_helper.rb",
51
+ "examples/lib/sinatra/resource_example.rb",
52
+ "examples/models.rb"
53
+ ]
54
+
55
+ if s.respond_to? :specification_version then
56
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
57
+ s.specification_version = 3
58
+
59
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
60
+ s.add_runtime_dependency(%q<sinatra>, [">= 1.0"])
61
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
62
+ s.add_runtime_dependency(%q<mongo_mapper>, [">= 0.7.6"])
63
+ s.add_development_dependency(%q<micronaut>, [">= 0.3.0"])
64
+ s.add_development_dependency(%q<rack-test>, [">= 0.5.3"])
65
+ else
66
+ s.add_dependency(%q<sinatra>, [">= 1.0"])
67
+ s.add_dependency(%q<activesupport>, [">= 2.3.5"])
68
+ s.add_dependency(%q<mongo_mapper>, [">= 0.7.6"])
69
+ s.add_dependency(%q<micronaut>, [">= 0.3.0"])
70
+ s.add_dependency(%q<rack-test>, [">= 0.5.3"])
71
+ end
72
+ else
73
+ s.add_dependency(%q<sinatra>, [">= 1.0"])
74
+ s.add_dependency(%q<activesupport>, [">= 2.3.5"])
75
+ s.add_dependency(%q<mongo_mapper>, [">= 0.7.6"])
76
+ s.add_dependency(%q<micronaut>, [">= 0.3.0"])
77
+ s.add_dependency(%q<rack-test>, [">= 0.5.3"])
78
+ end
79
+ end
80
+
metadata ADDED
@@ -0,0 +1,170 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resource_mapper
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Adam Elliot
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-06-24 00:00:00 -06:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: sinatra
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 1
32
+ - 0
33
+ version: "1.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: activesupport
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 9
45
+ segments:
46
+ - 2
47
+ - 3
48
+ - 5
49
+ version: 2.3.5
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: mongo_mapper
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 15
61
+ segments:
62
+ - 0
63
+ - 7
64
+ - 6
65
+ version: 0.7.6
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: micronaut
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 19
77
+ segments:
78
+ - 0
79
+ - 3
80
+ - 0
81
+ version: 0.3.0
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: rack-test
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 13
93
+ segments:
94
+ - 0
95
+ - 5
96
+ - 3
97
+ version: 0.5.3
98
+ type: :development
99
+ version_requirements: *id005
100
+ description: Creates a resource for a model in sinatra
101
+ email: adam@adamelliot.com
102
+ executables: []
103
+
104
+ extensions: []
105
+
106
+ extra_rdoc_files:
107
+ - LICENSE
108
+ - README.rdoc
109
+ files:
110
+ - .autotest
111
+ - .document
112
+ - .gitignore
113
+ - LICENSE
114
+ - README.rdoc
115
+ - Rakefile
116
+ - VERSION
117
+ - examples/example_helper.rb
118
+ - examples/lib/sinatra/resource_example.rb
119
+ - examples/models.rb
120
+ - lib/resource_mapper.rb
121
+ - lib/resource_mapper/accessors.rb
122
+ - lib/resource_mapper/action_options.rb
123
+ - lib/resource_mapper/actions.rb
124
+ - lib/resource_mapper/class_methods.rb
125
+ - lib/resource_mapper/controller.rb
126
+ - lib/resource_mapper/failable_action_options.rb
127
+ - lib/resource_mapper/helpers/current_objects.rb
128
+ - lib/resource_mapper/helpers/internal.rb
129
+ - lib/resource_mapper/helpers/nested.rb
130
+ - lib/resource_mapper/response_collector.rb
131
+ - lib/sinatra/resource.rb
132
+ - resource_mapper.gemspec
133
+ has_rdoc: true
134
+ homepage: http://github.com/adamelliot/resource_mapper
135
+ licenses: []
136
+
137
+ post_install_message:
138
+ rdoc_options:
139
+ - --charset=UTF-8
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ hash: 3
148
+ segments:
149
+ - 0
150
+ version: "0"
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ requirements: []
161
+
162
+ rubyforge_project:
163
+ rubygems_version: 1.3.7
164
+ signing_key:
165
+ specification_version: 3
166
+ summary: A resource_controller derivate that brings similar functionality to Sinatra, but provides a simple way to create restful APIs
167
+ test_files:
168
+ - examples/example_helper.rb
169
+ - examples/lib/sinatra/resource_example.rb
170
+ - examples/models.rb