rc_rails 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/CHANGELOG +355 -0
- data/Gemfile +5 -0
- data/Gemfile.lock.development +117 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +71 -0
- data/Rakefile +33 -0
- data/Todo.txt +1 -0
- data/lib/rc_rails.rb +9 -0
- data/lib/resources_controller/actions.rb +147 -0
- data/lib/resources_controller/active_record/saved.rb +15 -0
- data/lib/resources_controller/helper.rb +123 -0
- data/lib/resources_controller/include_actions.rb +37 -0
- data/lib/resources_controller/named_route_helper.rb +154 -0
- data/lib/resources_controller/railtie.rb +14 -0
- data/lib/resources_controller/request_path_introspection.rb +83 -0
- data/lib/resources_controller/resource_methods.rb +32 -0
- data/lib/resources_controller/singleton_actions.rb +21 -0
- data/lib/resources_controller/specification.rb +119 -0
- data/lib/resources_controller/version.rb +3 -0
- data/lib/resources_controller.rb +849 -0
- data/resources_controller.gemspec +29 -0
- data/spec/app/database.yml +5 -0
- data/spec/app/views/accounts/show.html.erb +0 -0
- data/spec/app/views/addresses/edit.html.erb +0 -0
- data/spec/app/views/addresses/index.html.erb +0 -0
- data/spec/app/views/addresses/new.html.erb +0 -0
- data/spec/app/views/addresses/show.html.erb +0 -0
- data/spec/app/views/admin/forums/create.html.erb +0 -0
- data/spec/app/views/admin/forums/destroy.html.erb +0 -0
- data/spec/app/views/admin/forums/edit.html.erb +0 -0
- data/spec/app/views/admin/forums/index.html.erb +0 -0
- data/spec/app/views/admin/forums/new.html.erb +0 -0
- data/spec/app/views/admin/forums/show.html.erb +0 -0
- data/spec/app/views/admin/forums/update.html.erb +0 -0
- data/spec/app/views/comments/edit.html.erb +0 -0
- data/spec/app/views/comments/index.html.erb +0 -0
- data/spec/app/views/comments/new.html.erb +0 -0
- data/spec/app/views/comments/show.html.erb +0 -0
- data/spec/app/views/forum_posts/edit.html.erb +0 -0
- data/spec/app/views/forum_posts/index.html.erb +0 -0
- data/spec/app/views/forum_posts/new.html.erb +0 -0
- data/spec/app/views/forum_posts/show.html.erb +0 -0
- data/spec/app/views/forums/create.html.erb +0 -0
- data/spec/app/views/forums/destroy.html.erb +0 -0
- data/spec/app/views/forums/edit.html.erb +0 -0
- data/spec/app/views/forums/index.html.erb +0 -0
- data/spec/app/views/forums/new.html.erb +0 -0
- data/spec/app/views/forums/show.html.erb +0 -0
- data/spec/app/views/forums/update.html.erb +0 -0
- data/spec/app/views/infos/edit.html.erb +0 -0
- data/spec/app/views/infos/show.html.erb +0 -0
- data/spec/app/views/interests/index.html.erb +0 -0
- data/spec/app/views/interests/show.html.erb +0 -0
- data/spec/app/views/owners/edit.html.erb +0 -0
- data/spec/app/views/owners/new.html.erb +0 -0
- data/spec/app/views/owners/show.html.erb +0 -0
- data/spec/app/views/tags/index.html.erb +0 -0
- data/spec/app/views/tags/new.html.erb +0 -0
- data/spec/app/views/tags/show.html.erb +0 -0
- data/spec/app/views/users/edit.html.erb +0 -0
- data/spec/app/views/users/index.html.erb +0 -0
- data/spec/app/views/users/show.html.erb +0 -0
- data/spec/app.rb +315 -0
- data/spec/controllers/accounts_controller_spec.rb +77 -0
- data/spec/controllers/addresses_controller_spec.rb +346 -0
- data/spec/controllers/admin_forums_controller_spec.rb +638 -0
- data/spec/controllers/comments_controller_spec.rb +380 -0
- data/spec/controllers/comments_controller_with_models_spec.rb +202 -0
- data/spec/controllers/forum_posts_controller_spec.rb +426 -0
- data/spec/controllers/forums_controller_spec.rb +694 -0
- data/spec/controllers/infos_controller_spec.rb +71 -0
- data/spec/controllers/interests_controller_via_forum_spec.rb +80 -0
- data/spec/controllers/interests_controller_via_user_spec.rb +114 -0
- data/spec/controllers/owners_controller_spec.rb +277 -0
- data/spec/controllers/resource_saved_spec.rb +47 -0
- data/spec/controllers/resource_service_in_forums_controller_spec.rb +37 -0
- data/spec/controllers/resource_service_in_infos_controller_spec.rb +36 -0
- data/spec/controllers/resource_service_in_interests_controller_via_forum_spec.rb +51 -0
- data/spec/controllers/tags_controller_spec.rb +83 -0
- data/spec/controllers/tags_controller_via_account_info_spec.rb +131 -0
- data/spec/controllers/tags_controller_via_forum_post_comment_spec.rb +144 -0
- data/spec/controllers/tags_controller_via_forum_post_spec.rb +133 -0
- data/spec/controllers/tags_controller_via_forum_spec.rb +173 -0
- data/spec/controllers/tags_controller_via_user_address_spec.rb +130 -0
- data/spec/controllers/users_controller_spec.rb +248 -0
- data/spec/lib/action_view_helper_spec.rb +143 -0
- data/spec/lib/bug_0001_spec.rb +22 -0
- data/spec/lib/include_actions_spec.rb +35 -0
- data/spec/lib/load_enclosing_resources_spec.rb +245 -0
- data/spec/lib/request_path_introspection_spec.rb +130 -0
- data/spec/lib/resource_methods_spec.rb +204 -0
- data/spec/lib/resources_controller_spec.rb +57 -0
- data/spec/models/comment_saved_spec.rb +24 -0
- data/spec/rspec_generator_task.rb +105 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/verify_rcov.rb +52 -0
- metadata +193 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
module ResourcesController
|
2
|
+
# This class holds all the info that is required to find a resource, or determine a name prefix, based on a route segment
|
3
|
+
# or segment pair (e.g. /blog or /users/3).
|
4
|
+
#
|
5
|
+
# You don't need to instantiate this class directly - it is created by ResourcesController::ClassMethods#nested_in,
|
6
|
+
# ResourcesController#map_resource (and ResourcesController::InstanceMethods#load_wildcard)
|
7
|
+
#
|
8
|
+
# This is primarily a container class. A summary of its behaviour:
|
9
|
+
# 1. setting defaults for its own variables on initialize, and
|
10
|
+
# 2. finding an enclosing resource, given a controller object
|
11
|
+
#
|
12
|
+
class Specification
|
13
|
+
|
14
|
+
# raised when we try and constantize a class that doesn't exist
|
15
|
+
class NoClassFoundError < NameError
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :name, :source, :klass, :key, :name_prefix, :segment, :find
|
19
|
+
attr_accessor :as
|
20
|
+
|
21
|
+
# factory for Specification and SingletonSpecification
|
22
|
+
#
|
23
|
+
# you can call Specification.new 'name', :singleton => true
|
24
|
+
def self.new(name, options = {}, &block)
|
25
|
+
options.delete(:singleton) ? SingletonSpecification.new(name, options, &block) : super(name, options, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Example Usage
|
29
|
+
#
|
30
|
+
# Specifcation.new <name>, <options hash>, <&block>
|
31
|
+
#
|
32
|
+
# _name_ should always be singular.
|
33
|
+
#
|
34
|
+
# Options:
|
35
|
+
#
|
36
|
+
# * <tt>:singleton:</tt> (default false) set this to true if the resource is a Singleton
|
37
|
+
# * <tt>:find:</tt> (default null) set this to a symbol or Proc to specify how to find the resource.
|
38
|
+
# Use this if the resource is found in an unconventional way
|
39
|
+
#
|
40
|
+
# Options for unconvential use (otherwise these are all inferred from the _name_)
|
41
|
+
# * <tt>:source:</tt> a plural string or symbol (e.g. :users). This is used to find the class or association name
|
42
|
+
# * <tt>:class:</tt> a Class. This is the class of the resource (if it can't be inferred from _name_ or :source)
|
43
|
+
# * <tt>:key:</tt> (e.g. :user_id) used to find the resource id in params
|
44
|
+
# * <tt>:name_prefix:</tt> (e.g. 'user_') (set this to false if you want to specify that there is none)
|
45
|
+
# * <tt>:segment:</tt> (e.g. 'users') the segment name in the route that is matched
|
46
|
+
#
|
47
|
+
# Passing a block is the same as passing :find => Proc
|
48
|
+
def initialize(spec_name, options = {}, &block)
|
49
|
+
options.assert_valid_keys(:class, :source, :key, :find, :name_prefix, :segment, :as)
|
50
|
+
@name = spec_name.to_s
|
51
|
+
@find = block || options.delete(:find)
|
52
|
+
@segment = (options[:segment] && options[:segment].to_s) || name.pluralize
|
53
|
+
@source = (options[:source] && options[:source].to_s) || name.pluralize
|
54
|
+
@name_prefix = options[:name_prefix] || (options[:name_prefix] == false ? '' : "#{name}_")
|
55
|
+
@klass = options[:class] || infer_class
|
56
|
+
@key = (options[:key] && options[:key].to_s) || name.foreign_key
|
57
|
+
@as = options[:as]
|
58
|
+
end
|
59
|
+
|
60
|
+
# returns false
|
61
|
+
def singleton?
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
# given a controller object, returns the resource according to this specification
|
66
|
+
def find_from(controller)
|
67
|
+
find ? find_custom(controller) : find_resource(controller)
|
68
|
+
end
|
69
|
+
|
70
|
+
# finds the resource using the custom :find Proc or symbol
|
71
|
+
def find_custom(controller)
|
72
|
+
raise "This specification has no custom :find attribute" unless find
|
73
|
+
find.is_a?(Proc) ? controller.instance_exec(&find) : controller.send(find)
|
74
|
+
end
|
75
|
+
|
76
|
+
# finds the resource on a controller using enclosing resources or resource class
|
77
|
+
def find_resource(controller)
|
78
|
+
(controller.enclosing_resource ? controller.enclosing_resource.send(source) : klass).find controller.params[key]
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def infer_class
|
83
|
+
((source && source.classify) || name.camelize).constantize
|
84
|
+
rescue NameError => e
|
85
|
+
raise NoClassFoundError, "Cound't find class for name: #{name.inspect}, source: #{source.inspect}: #{e.message}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# A Singleton Specification
|
90
|
+
class SingletonSpecification < Specification
|
91
|
+
# Same as Specification except:
|
92
|
+
#
|
93
|
+
# Options for unconvential use (otherwise these are all inferred from the _name_)
|
94
|
+
# * <tt>:source:</tt> a singular string or symbol (e.g. :blog). This is used to find the class or association name
|
95
|
+
# * <tt>:segment:</tt> (e.g. 'blog') the segment name in the route that is matched
|
96
|
+
def initialize(spec_name, options = {}, &block)
|
97
|
+
options[:segment] ||= spec_name.to_s
|
98
|
+
options[:source] ||= spec_name.to_s
|
99
|
+
|
100
|
+
super(spec_name, options, &block)
|
101
|
+
end
|
102
|
+
|
103
|
+
# returns true
|
104
|
+
def singleton?
|
105
|
+
true
|
106
|
+
end
|
107
|
+
|
108
|
+
# no key for singleton resources
|
109
|
+
def key
|
110
|
+
false
|
111
|
+
end
|
112
|
+
|
113
|
+
# finds the resource from the enclosing resource. Raise CantFindSingleton if there is no enclosing resource
|
114
|
+
def find_resource(controller)
|
115
|
+
ResourcesController.raise_cant_find_singleton(name, klass) unless controller.enclosing_resource
|
116
|
+
controller.enclosing_resource.send(source)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|