eac-resourcify 0.1.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.
data/lib/resourcify.rb ADDED
@@ -0,0 +1,26 @@
1
+ # make sure we're running inside Merb
2
+ if defined?(Merb::Plugins)
3
+ require 'extlib'
4
+
5
+ Merb::BootLoader.before_app_loads do
6
+ # require code that must be loaded before the application
7
+ require 'resourcify/data_mapper/parents'
8
+ require 'resourcify/data_mapper/serialize_errors'
9
+ ::DataMapper::Model.append_extensions(Resourcify::DataMapper::Parents)
10
+ ::DataMapper::Resource.append_inclusions(Resourcify::DataMapper::SerializeErrors)
11
+
12
+ require 'resourcify/controller'
13
+ require 'resourcify/resource'
14
+ require 'resourcify/actions'
15
+ require 'resourcify/responses'
16
+ require 'resourcify/parent_relationship'
17
+ Merb::Controller.send(:extend, Resourcify::Controller)
18
+ end
19
+
20
+ Merb::BootLoader.after_app_loads do
21
+ # code that can be required after the application loads
22
+ end
23
+
24
+ # Merb::Plugins.add_rakefiles "resourcify/merbtasks"
25
+
26
+ end
@@ -0,0 +1,56 @@
1
+ module Resourcify
2
+ module Actions
3
+
4
+ protected
5
+
6
+ # UI Actions
7
+ def new
8
+ only_provides :html
9
+ resource
10
+ render
11
+ end
12
+
13
+ def edit
14
+ only_provides :html
15
+ resource
16
+ render
17
+ end
18
+
19
+ private
20
+
21
+ # Verbs
22
+
23
+ def get
24
+ display resource
25
+ end
26
+
27
+ def put
28
+ if resource.save
29
+ put_successful
30
+ else
31
+ put_failed
32
+ end
33
+ end
34
+
35
+ def post
36
+ if resource.save
37
+ post_successful
38
+ else
39
+ post_failed
40
+ end
41
+ end
42
+
43
+ def delete
44
+ resource.destroy || raise(StandardError.new("Failed to destroy resource: #{resource.inspect}"))
45
+ delete_successful
46
+ end
47
+
48
+ # Quick compatiblity with Resourceful Routes
49
+ alias_method :index, :get
50
+ alias_method :show, :get
51
+ alias_method :destroy, :delete
52
+ alias_method :update, :put
53
+ alias_method :create, :post
54
+
55
+ end
56
+ end
@@ -0,0 +1,14 @@
1
+ module Resourcify
2
+ module Controller
3
+
4
+ def resourcify
5
+
6
+ include Resource
7
+ include Actions
8
+ include Responses
9
+ include ParentRelationship
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ module Resourcify
2
+ module DataMapper
3
+ module Parents
4
+
5
+ # FIXME Only works for single-field foreign keys
6
+ def parent_keys
7
+ parent_relationships.keys
8
+ end
9
+
10
+ # FIXME Not grabbing proper relationships
11
+ def parent_relationships
12
+ parent_relationships = {}
13
+ relationships.each do |relationship_name, relationship|
14
+ if relationship.child_model == self
15
+ parent_key = relationship.child_key.entries.first.field.to_sym
16
+ parent_relationships[parent_key] = relationship
17
+ end
18
+ end
19
+ parent_relationships
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module Resourcify
2
+ module DataMapper
3
+ module SerializeErrors
4
+
5
+ def serialize_properties
6
+ errors.blank? ? {} : { :errors => errors.send(:errors) }
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,72 @@
1
+ module Resourcify
2
+ module ParentRelationship
3
+
4
+
5
+ # e.g.
6
+ # class Person
7
+ # belongs_to :location
8
+ # end
9
+ #
10
+ # class Location
11
+ # has n, :people
12
+ # end
13
+ #
14
+ # access_by :location
15
+ #
16
+ # (Options)
17
+ # :collection => :person
18
+ #
19
+ def self.included(base)
20
+ base.class_eval do
21
+ class_inheritable_accessor :relationship_collections
22
+ self.relationship_collections = {}
23
+
24
+ def self.access_by(relationship, options = {})
25
+ options[:collection] ||= Extlib::Inflection.tableize(model_name_parts.last).to_sym
26
+
27
+ relationship_collections[relationship] = options[:collection]
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ def owner
35
+ collection || model
36
+ end
37
+
38
+ def parent
39
+ @parent ||= parent_relationship.parent_model.get!(params[parent_key]) if parent_relationship?
40
+ end
41
+
42
+ def collection(query = {})
43
+ if parent_relationship?
44
+ if association_name = relationship_collections[parent_relationship.name]
45
+ parent.send(association_name, query)
46
+ else
47
+ raise(ArgumentError.new(
48
+ "Parent relationship #{parent_relationship.name} found, but not marked as accessible.
49
+ Specify `access_by :#{parent_relationship.name}` for this controller."
50
+ ))
51
+ end
52
+ end
53
+ end
54
+
55
+ def relationship_collections
56
+ self.class.relationship_collections
57
+ end
58
+
59
+ def parent_relationship?
60
+ !parent_relationship.nil?
61
+ end
62
+
63
+ def parent_relationship
64
+ @parent_relationship ||= model.parent_relationships[parent_key]
65
+ end
66
+
67
+ def parent_key
68
+ @parent_key ||= model.parent_keys.detect { |parent_key| params[parent_key] }
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,104 @@
1
+ module Resourcify
2
+ module Resource
3
+
4
+ def self.included(base)
5
+
6
+ base.class_eval do
7
+ def self.model
8
+ Extlib::Inflection.constantize(model_name)
9
+ rescue NameError
10
+ raise NameError.new(
11
+ "Could not find a model named #{model_name}. Override #{self.name}.model_name with an existing class."
12
+ )
13
+ end
14
+
15
+ protected
16
+
17
+ def self.model_name
18
+ model_name_parts.join('::')
19
+ end
20
+
21
+ def self.model_name_parts
22
+ name_parts = name.split('::')
23
+ model_name = name_parts.pop.singular
24
+ name_parts << model_name
25
+ end
26
+
27
+ def self.resources_path
28
+ Extlib::Inflection.tableize(model_name)
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ # def self.inherited(subclass)
36
+ # subclass.model = Kernel.const_get(subclass.name.singular)
37
+ # end
38
+
39
+ protected
40
+
41
+ # Resources
42
+
43
+ def model
44
+ self.class.model
45
+ end
46
+
47
+ def resource_url
48
+ url(self.class.resources_path.singular.to_sym, resource.key)
49
+ end
50
+
51
+ def resource_collection_url
52
+ url(self.class.resources_path.to_sym)
53
+ end
54
+
55
+ def resource
56
+ @resource ||= assign_resource_instance_variable
57
+ end
58
+
59
+ def fetch_resource
60
+ case params[:action]
61
+ when *self.class.load_actions then load_resource
62
+ when *self.class.build_actions then build_resource
63
+ else
64
+ raise ArgumentError, "Unknown resource action #{params[:action].inspect}"
65
+ end
66
+ end
67
+
68
+ def build_resource
69
+ parent ? owner.build(resource_params || {}) : owner.new(resource_params || {})
70
+ end
71
+
72
+ def load_resource
73
+ params[:id] ? owner.get!(params[:id]) : owner.all
74
+ end
75
+
76
+ def resource_params
77
+ params[model.name.snake_case]
78
+ end
79
+
80
+ # ParentRelationships overrides this method.
81
+ def owner
82
+ model
83
+ end
84
+
85
+ private
86
+
87
+ # FIXME Rewrite
88
+ # Equivelent to @users = User.all or @user = User.get!(id)
89
+ # TODO Dynamically create method?
90
+ # def resource #{singular_name} = fetch_resource end
91
+ # def resources #{plural_name} = fetch_resource end
92
+ def assign_resource_instance_variable
93
+ fetched_resource = fetch_resource
94
+ base_name = Extlib::Inflection.underscore(
95
+ Extlib::Inflection.demodulize(self.class.name)
96
+ ).downcase
97
+ instance_variable_name = fetched_resource.is_a?(Array) ? "@#{base_name}" : "@#{base_name.singular}"
98
+ instance_variable_set(instance_variable_name, fetched_resource)
99
+ end
100
+
101
+
102
+
103
+ end
104
+ end
@@ -0,0 +1,50 @@
1
+ module Resourcify
2
+ module Responses
3
+
4
+ # Responses
5
+ # Success
6
+ def put_successful
7
+ case content_type
8
+ when :html then redirect(resource_url)
9
+ else
10
+ self.status = 204 # No Content
11
+ ''
12
+ end
13
+ end
14
+
15
+ def delete_successful
16
+ case content_type
17
+ when :html then redirect(resource_collection_url)
18
+ else
19
+ self.status = 204 # No Content
20
+ ''
21
+ end
22
+ end
23
+
24
+ def post_successful
25
+ case content_type
26
+ when :html then redirect(resource_url)
27
+ else
28
+ display(resource, :status => 201, :location => resource_url) # 201 Created
29
+ end
30
+ end
31
+
32
+ # Failure 422 Unproccessable entity
33
+ def post_failed
34
+ case content_type
35
+ when :html then render(:new, :status => 422)
36
+ else
37
+ display(resource, :status => 422)
38
+ end
39
+ end
40
+
41
+ def put_failed
42
+ case content_type
43
+ when :html then render(:edit, :status => 422)
44
+ else
45
+ display(resource, :status => 422)
46
+ end
47
+ end
48
+
49
+ end
50
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eac-resourcify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Eric Chapweske
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-09-29 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Basic enhancements for making Merb controllers more resourceful. Provides reduced code duplication, nested resource support, and aims for RFC2616 compliant responses.
17
+ email: eric@slantwisedesign.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/resourcify.rb
26
+ - lib/resourcify/controller.rb
27
+ - lib/resourcify/actions.rb
28
+ - lib/resourcify/parent_relationship.rb
29
+ - lib/resourcify/resource.rb
30
+ - lib/resourcify/responses.rb
31
+ - lib/resourcify/data_mapper/parents.rb
32
+ - lib/resourcify/data_mapper/serialize_errors.rb
33
+ has_rdoc: true
34
+ homepage:
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.8.6
45
+ version:
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ requirements:
53
+ - Install datamapper to get full functionality out of the box.
54
+ rubyforge_project:
55
+ rubygems_version: 1.2.0
56
+ signing_key:
57
+ specification_version: 2
58
+ summary: Resourceful merb controllers.
59
+ test_files: []
60
+