base_rails_app 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/LICENSE +1 -0
  2. data/README +1 -0
  3. data/lib/app/controllers/application_controller.rb +55 -0
  4. data/lib/app/controllers/password_resets_controller.rb +45 -0
  5. data/lib/app/controllers/user_sessions_controller.rb +25 -0
  6. data/lib/app/controllers/users_controller.rb +37 -0
  7. data/lib/app/helpers/application_helper.rb +4 -0
  8. data/lib/app/helpers/user_sessions_helper.rb +2 -0
  9. data/lib/app/helpers/users_helper.rb +2 -0
  10. data/lib/app/models/postman.rb +20 -0
  11. data/lib/app/models/user.rb +12 -0
  12. data/lib/app/models/user_session.rb +2 -0
  13. data/lib/app/views/application/404_not_found.html.erb +8 -0
  14. data/lib/app/views/layouts/application.html.erb +57 -0
  15. data/lib/app/views/password_resets/_sidebar.html.erb +0 -0
  16. data/lib/app/views/password_resets/edit.html.erb +33 -0
  17. data/lib/app/views/password_resets/new.html.erb +26 -0
  18. data/lib/app/views/postman/password_reset_instructions.html.erb +3 -0
  19. data/lib/app/views/postman/welcome_email.html.erb +3 -0
  20. data/lib/app/views/user_sessions/_form.html.erb +19 -0
  21. data/lib/app/views/user_sessions/_sidebar.html.erb +13 -0
  22. data/lib/app/views/user_sessions/new.html.erb +15 -0
  23. data/lib/app/views/users/_form.html.erb +28 -0
  24. data/lib/app/views/users/_sidebar.html.erb +6 -0
  25. data/lib/app/views/users/edit.html.erb +19 -0
  26. data/lib/app/views/users/new.html.erb +15 -0
  27. data/lib/app/views/users/show.html.erb +46 -0
  28. data/lib/base_rails_app.rb +5 -0
  29. data/lib/base_rails_app/boot.rb +2 -0
  30. data/lib/base_rails_app/tasks.rb +12 -0
  31. data/lib/config/configatron/cucumber.rb +0 -0
  32. data/lib/config/configatron/defaults.rb +4 -0
  33. data/lib/config/configatron/development.rb +1 -0
  34. data/lib/config/configatron/production.rb +0 -0
  35. data/lib/config/configatron/test.rb +0 -0
  36. data/lib/config/database.yml +25 -0
  37. data/lib/config/deploy.rb +15 -0
  38. data/lib/config/environments/cucumber.rb +22 -0
  39. data/lib/config/environments/development.rb +17 -0
  40. data/lib/config/environments/production.rb +28 -0
  41. data/lib/config/environments/test.rb +28 -0
  42. data/lib/config/gemtronics.rb +36 -0
  43. data/lib/config/initializers/backtrace_silencers.rb +7 -0
  44. data/lib/config/initializers/configatron.rb +1 -0
  45. data/lib/config/initializers/hoptoad.rb +3 -0
  46. data/lib/config/initializers/inflections.rb +10 -0
  47. data/lib/config/initializers/mailers.rb +1 -0
  48. data/lib/config/initializers/mime_types.rb +5 -0
  49. data/lib/config/initializers/new_rails_defaults.rb +21 -0
  50. data/lib/config/initializers/session_store.rb +17 -0
  51. data/lib/config/locales/en.yml +5 -0
  52. data/lib/config/routes.rb +51 -0
  53. data/lib/config/schedule.rb +20 -0
  54. data/lib/db/migrate/20090809175903_create_users.rb +30 -0
  55. data/lib/db/migrate/20090809204840_acts_as_taggable_on_migration.rb +29 -0
  56. data/lib/db/migrate/20090912171353_create_delayed_jobs.rb +20 -0
  57. data/lib/db/migrate/20090912171829_add_delayed_job_extras.rb +11 -0
  58. data/lib/db/migrate/20090929201455_add_more_time_columns_to_dj.rb +11 -0
  59. data/lib/db/schema.rb +72 -0
  60. data/lib/db/seeds.rb +7 -0
  61. data/lib/lib/tasks/cucumber.rake +36 -0
  62. data/lib/lib/tasks/rcov.rake +27 -0
  63. data/lib/lib/tasks/rspec.rake +183 -0
  64. data/lib/vendor/plugins/delayed_job/generators/delayed_job/delayed_job_generator.rb +22 -0
  65. data/lib/vendor/plugins/delayed_job/generators/delayed_job/templates/migration.rb +20 -0
  66. data/lib/vendor/plugins/delayed_job/init.rb +2 -0
  67. data/lib/vendor/plugins/delayed_job/lib/delayed/command.rb +65 -0
  68. data/lib/vendor/plugins/delayed_job/lib/delayed/job.rb +271 -0
  69. data/lib/vendor/plugins/delayed_job/lib/delayed/message_sending.rb +18 -0
  70. data/lib/vendor/plugins/delayed_job/lib/delayed/performable_method.rb +55 -0
  71. data/lib/vendor/plugins/delayed_job/lib/delayed/tasks.rb +15 -0
  72. data/lib/vendor/plugins/delayed_job/lib/delayed/worker.rb +54 -0
  73. data/lib/vendor/plugins/delayed_job/lib/delayed_job.rb +13 -0
  74. data/lib/vendor/plugins/delayed_job/recipes/delayed_job.rb +26 -0
  75. data/lib/vendor/plugins/delayed_job/tasks/jobs.rake +1 -0
  76. data/lib/vendor/plugins/hoptoad_notifier/install.rb +1 -0
  77. data/lib/vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier.rb +418 -0
  78. data/lib/vendor/plugins/hoptoad_notifier/lib/hoptoad_tasks.rb +26 -0
  79. data/lib/vendor/plugins/hoptoad_notifier/recipes/hoptoad.rb +22 -0
  80. data/lib/vendor/plugins/hoptoad_notifier/tasks/hoptoad_notifier_tasks.rake +66 -0
  81. data/lib/vendor/plugins/inherited_resources/README.rdoc +524 -0
  82. data/lib/vendor/plugins/inherited_resources/inherited_resources.gemspec +71 -0
  83. data/lib/vendor/plugins/inherited_resources/init.rb +1 -0
  84. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources.rb +23 -0
  85. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/actions.rb +79 -0
  86. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/base.rb +42 -0
  87. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/base_helpers.rb +363 -0
  88. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/belongs_to_helpers.rb +89 -0
  89. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/class_methods.rb +338 -0
  90. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/dsl.rb +26 -0
  91. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/dumb_responder.rb +20 -0
  92. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/has_scope_helpers.rb +83 -0
  93. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/legacy/respond_to.rb +156 -0
  94. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/legacy/responder.rb +200 -0
  95. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/polymorphic_helpers.rb +155 -0
  96. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/singleton_helpers.rb +95 -0
  97. data/lib/vendor/plugins/inherited_resources/lib/inherited_resources/url_helpers.rb +179 -0
  98. data/lib/vendor/plugins/inherited_resources/test/aliases_test.rb +139 -0
  99. data/lib/vendor/plugins/inherited_resources/test/association_chain_test.rb +125 -0
  100. data/lib/vendor/plugins/inherited_resources/test/base_test.rb +225 -0
  101. data/lib/vendor/plugins/inherited_resources/test/belongs_to_test.rb +87 -0
  102. data/lib/vendor/plugins/inherited_resources/test/class_methods_test.rb +138 -0
  103. data/lib/vendor/plugins/inherited_resources/test/customized_base_test.rb +162 -0
  104. data/lib/vendor/plugins/inherited_resources/test/customized_belongs_to_test.rb +76 -0
  105. data/lib/vendor/plugins/inherited_resources/test/defaults_test.rb +70 -0
  106. data/lib/vendor/plugins/inherited_resources/test/flash_test.rb +88 -0
  107. data/lib/vendor/plugins/inherited_resources/test/has_scope_test.rb +139 -0
  108. data/lib/vendor/plugins/inherited_resources/test/locales/en.yml +17 -0
  109. data/lib/vendor/plugins/inherited_resources/test/nested_belongs_to_test.rb +108 -0
  110. data/lib/vendor/plugins/inherited_resources/test/optional_belongs_to_test.rb +164 -0
  111. data/lib/vendor/plugins/inherited_resources/test/polymorphic_test.rb +186 -0
  112. data/lib/vendor/plugins/inherited_resources/test/redirect_to_test.rb +51 -0
  113. data/lib/vendor/plugins/inherited_resources/test/respond_to_test.rb +155 -0
  114. data/lib/vendor/plugins/inherited_resources/test/singleton_test.rb +83 -0
  115. data/lib/vendor/plugins/inherited_resources/test/test_helper.rb +38 -0
  116. data/lib/vendor/plugins/inherited_resources/test/url_helpers_test.rb +537 -0
  117. data/lib/vendor/plugins/inherited_resources/test/views/cars/edit.html.erb +1 -0
  118. data/lib/vendor/plugins/inherited_resources/test/views/cars/index.html.erb +1 -0
  119. data/lib/vendor/plugins/inherited_resources/test/views/cars/new.html.erb +1 -0
  120. data/lib/vendor/plugins/inherited_resources/test/views/cars/show.html.erb +1 -0
  121. data/lib/vendor/plugins/inherited_resources/test/views/cities/edit.html.erb +1 -0
  122. data/lib/vendor/plugins/inherited_resources/test/views/cities/index.html.erb +1 -0
  123. data/lib/vendor/plugins/inherited_resources/test/views/cities/new.html.erb +1 -0
  124. data/lib/vendor/plugins/inherited_resources/test/views/cities/show.html.erb +1 -0
  125. data/lib/vendor/plugins/inherited_resources/test/views/comments/edit.html.erb +1 -0
  126. data/lib/vendor/plugins/inherited_resources/test/views/comments/index.html.erb +1 -0
  127. data/lib/vendor/plugins/inherited_resources/test/views/comments/new.html.erb +1 -0
  128. data/lib/vendor/plugins/inherited_resources/test/views/comments/show.html.erb +1 -0
  129. data/lib/vendor/plugins/inherited_resources/test/views/employees/edit.html.erb +1 -0
  130. data/lib/vendor/plugins/inherited_resources/test/views/employees/index.html.erb +1 -0
  131. data/lib/vendor/plugins/inherited_resources/test/views/employees/new.html.erb +1 -0
  132. data/lib/vendor/plugins/inherited_resources/test/views/employees/show.html.erb +1 -0
  133. data/lib/vendor/plugins/inherited_resources/test/views/managers/edit.html.erb +1 -0
  134. data/lib/vendor/plugins/inherited_resources/test/views/managers/new.html.erb +1 -0
  135. data/lib/vendor/plugins/inherited_resources/test/views/managers/show.html.erb +1 -0
  136. data/lib/vendor/plugins/inherited_resources/test/views/painters/edit.html.erb +1 -0
  137. data/lib/vendor/plugins/inherited_resources/test/views/painters/index.html.erb +1 -0
  138. data/lib/vendor/plugins/inherited_resources/test/views/painters/new.html.erb +1 -0
  139. data/lib/vendor/plugins/inherited_resources/test/views/painters/show.html.erb +1 -0
  140. data/lib/vendor/plugins/inherited_resources/test/views/pets/edit.html.erb +1 -0
  141. data/lib/vendor/plugins/inherited_resources/test/views/pets/index.html.erb +1 -0
  142. data/lib/vendor/plugins/inherited_resources/test/views/pets/new.html.erb +1 -0
  143. data/lib/vendor/plugins/inherited_resources/test/views/pets/show.html.erb +1 -0
  144. data/lib/vendor/plugins/inherited_resources/test/views/products/edit.html.erb +1 -0
  145. data/lib/vendor/plugins/inherited_resources/test/views/products/index.html.erb +1 -0
  146. data/lib/vendor/plugins/inherited_resources/test/views/products/new.html.erb +1 -0
  147. data/lib/vendor/plugins/inherited_resources/test/views/products/show.html.erb +1 -0
  148. data/lib/vendor/plugins/inherited_resources/test/views/professors/edit.html.erb +1 -0
  149. data/lib/vendor/plugins/inherited_resources/test/views/professors/index.html.erb +1 -0
  150. data/lib/vendor/plugins/inherited_resources/test/views/professors/new.html.erb +1 -0
  151. data/lib/vendor/plugins/inherited_resources/test/views/professors/show.html.erb +1 -0
  152. data/lib/vendor/plugins/inherited_resources/test/views/projects/index.html.erb +1 -0
  153. data/lib/vendor/plugins/inherited_resources/test/views/projects/index.json.erb +1 -0
  154. data/lib/vendor/plugins/inherited_resources/test/views/projects/respond_to_skip_default_template.html.erb +1 -0
  155. data/lib/vendor/plugins/inherited_resources/test/views/projects/respond_with_resource.html.erb +1 -0
  156. data/lib/vendor/plugins/inherited_resources/test/views/students/edit.html.erb +1 -0
  157. data/lib/vendor/plugins/inherited_resources/test/views/students/new.html.erb +1 -0
  158. data/lib/vendor/plugins/inherited_resources/test/views/trees/edit.html.erb +1 -0
  159. data/lib/vendor/plugins/inherited_resources/test/views/trees/index.html.erb +1 -0
  160. data/lib/vendor/plugins/inherited_resources/test/views/trees/new.html.erb +1 -0
  161. data/lib/vendor/plugins/inherited_resources/test/views/trees/show.html.erb +1 -0
  162. data/lib/vendor/plugins/inherited_resources/test/views/users/edit.html.erb +1 -0
  163. data/lib/vendor/plugins/inherited_resources/test/views/users/index.html.erb +1 -0
  164. data/lib/vendor/plugins/inherited_resources/test/views/users/new.html.erb +1 -0
  165. data/lib/vendor/plugins/inherited_resources/test/views/users/show.html.erb +1 -0
  166. data/lib/vendor/plugins/web-app-theme/README.md +22 -0
  167. data/lib/vendor/plugins/web-app-theme/images/avatar.png +0 -0
  168. data/lib/vendor/plugins/web-app-theme/index.html +473 -0
  169. data/lib/vendor/plugins/web-app-theme/javascripts/jquery-1.3.min.js +19 -0
  170. data/lib/vendor/plugins/web-app-theme/javascripts/jquery.localscroll.js +104 -0
  171. data/lib/vendor/plugins/web-app-theme/javascripts/jquery.scrollTo.js +150 -0
  172. data/lib/vendor/plugins/web-app-theme/rails_generators/theme/templates/view_layout_administration.html.erb +48 -0
  173. data/lib/vendor/plugins/web-app-theme/rails_generators/theme/templates/view_layout_sign.html.erb +15 -0
  174. data/lib/vendor/plugins/web-app-theme/rails_generators/theme/theme_generator.rb +38 -0
  175. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_edit.html.erb +20 -0
  176. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_form.html.erb +10 -0
  177. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_new.html.erb +19 -0
  178. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_show.html.erb +23 -0
  179. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_sidebar.html.erb +13 -0
  180. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_signin.html.erb +39 -0
  181. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_signup.html.erb +56 -0
  182. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/templates/view_tables.html.erb +50 -0
  183. data/lib/vendor/plugins/web-app-theme/rails_generators/themed/themed_generator.rb +89 -0
  184. data/lib/vendor/plugins/web-app-theme/stylesheets/base.css +336 -0
  185. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/bec-green/style.css +290 -0
  186. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/bec/style.css +301 -0
  187. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/blue/style.css +280 -0
  188. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/default/style.css +267 -0
  189. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/djime-cerulean/style.css +298 -0
  190. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/drastic-dark/style.css +373 -0
  191. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/kathleene/style.css +272 -0
  192. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/orange/style.css +263 -0
  193. data/lib/vendor/plugins/web-app-theme/stylesheets/themes/reidb-greenish/style.css +301 -0
  194. metadata +257 -0
@@ -0,0 +1,89 @@
1
+ module InheritedResources
2
+
3
+ # = belongs_to
4
+ #
5
+ # Let's suppose that we have some tasks that belongs to projects. To specify
6
+ # this assoication in your controllers, just do:
7
+ #
8
+ # class TasksController < InheritedResources::Base
9
+ # belongs_to :project
10
+ # end
11
+ #
12
+ # belongs_to accepts several options to be able to configure the association.
13
+ # For example, if you want urls like /projects/:project_title/tasks, you
14
+ # can customize how InheritedResources find your projects:
15
+ #
16
+ # class TasksController < InheritedResources::Base
17
+ # belongs_to :project, :finder => :find_by_title!, :param => :project_title
18
+ # end
19
+ #
20
+ # It also accepts :route_name, :parent_class and :instance_name as options.
21
+ # Check the lib/inherited_resources/class_methods.rb for more.
22
+ #
23
+ # = nested_belongs_to
24
+ #
25
+ # Now, our Tasks get some Comments and you need to nest even deeper. Good
26
+ # practices says that you should never nest more than two resources, but sometimes
27
+ # you have to for security reasons. So this is an example of how you can do it:
28
+ #
29
+ # class CommentsController < InheritedResources::Base
30
+ # nested_belongs_to :project, :task
31
+ # end
32
+ #
33
+ # If you need to configure any of these belongs to, you can nested them using blocks:
34
+ #
35
+ # class CommentsController < InheritedResources::Base
36
+ # belongs_to :project, :finder => :find_by_title!, :param => :project_title do
37
+ # belongs_to :task
38
+ # end
39
+ # end
40
+ #
41
+ # Warning: calling several belongs_to is the same as nesting them:
42
+ #
43
+ # class CommentsController < InheritedResources::Base
44
+ # belongs_to :project
45
+ # belongs_to :task
46
+ # end
47
+ #
48
+ # In other words, the code above is the same as calling nested_belongs_to.
49
+ #
50
+ module BelongsToHelpers
51
+
52
+ protected
53
+
54
+ # Parent is always true when belongs_to is called.
55
+ #
56
+ def parent?
57
+ true
58
+ end
59
+
60
+ private
61
+
62
+ # Evaluate the parent given. This is used to nest parents in the
63
+ # association chain.
64
+ #
65
+ def evaluate_parent(parent_symbol, parent_config, chain = nil) #:nodoc:
66
+ instantiated_object = instance_variable_get("@#{parent_config[:instance_name]}")
67
+ return instantiated_object if instantiated_object
68
+
69
+ parent = if chain
70
+ chain.send(parent_config[:collection_name])
71
+ else
72
+ parent_config[:parent_class]
73
+ end
74
+
75
+ parent = parent.send(parent_config[:finder], params[parent_config[:param]])
76
+
77
+ instance_variable_set("@#{parent_config[:instance_name]}", parent)
78
+ end
79
+
80
+ # Maps parents_symbols to build association chain. In this case, it
81
+ # simply return the parent_symbols, however on polymorphic belongs to,
82
+ # it has some customization.
83
+ #
84
+ def symbols_for_association_chain #:nodoc:
85
+ parents_symbols
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,338 @@
1
+ module InheritedResources
2
+ module ClassMethods
3
+
4
+ protected
5
+
6
+ # Used to overwrite the default assumptions InheritedResources do. Whenever
7
+ # this method is called, it should be on the top of your controller, since
8
+ # almost other methods depends on the values given to <<tt>>defaults</tt>.
9
+ #
10
+ # == Options
11
+ #
12
+ # * <tt>:resource_class</tt> - The resource class which by default is guessed
13
+ # by the controller name. Defaults to Project in
14
+ # ProjectsController.
15
+ #
16
+ # * <tt>:collection_name</tt> - The name of the collection instance variable which
17
+ # is set on the index action. Defaults to :projects in
18
+ # ProjectsController.
19
+ #
20
+ # * <tt>:instance_name</tt> - The name of the singular instance variable which
21
+ # is set on all actions besides index action. Defaults to
22
+ # :project in ProjectsController.
23
+ #
24
+ # * <tt>:route_collection_name</tt> - The name of the collection route. Defaults to :collection_name.
25
+ #
26
+ # * <tt>:route_instance_name</tt> - The name of the singular route. Defaults to :instance_name.
27
+ #
28
+ # * <tt>:route_prefix</tt> - The route prefix which is automically set in namespaced
29
+ # controllers. Default to :admin on Admin::ProjectsController.
30
+ #
31
+ # * <tt>:singleton</tt> - Tells if this controller is singleton or not.
32
+ #
33
+ def defaults(options)
34
+ raise ArgumentError, 'Class method :defaults expects a hash of options.' unless options.is_a? Hash
35
+
36
+ options.symbolize_keys!
37
+ options.assert_valid_keys(:resource_class, :collection_name, :instance_name,
38
+ :class_name, :route_prefix, :route_collection_name,
39
+ :route_instance_name, :singleton)
40
+
41
+ self.resource_class = options.delete(:resource_class) if options.key?(:resource_class)
42
+ self.resource_class = options.delete(:class_name).constantize if options.key?(:class_name)
43
+
44
+ acts_as_singleton! if options.delete(:singleton)
45
+
46
+ config = self.resources_configuration[:self]
47
+ config[:route_prefix] = options.delete(:route_prefix) if options.key?(:route_prefix)
48
+
49
+ options.each do |key, value|
50
+ config[key] = value.to_sym
51
+ end
52
+
53
+ create_resources_url_helpers!
54
+ end
55
+
56
+ # Defines wich actions to keep from the inherited controller.
57
+ # Syntax is borrowed from resource_controller.
58
+ #
59
+ # actions :index, :show, :edit
60
+ # actions :all, :except => :index
61
+ #
62
+ def actions(*actions_to_keep)
63
+ raise ArgumentError, 'Wrong number of arguments. You have to provide which actions you want to keep.' if actions_to_keep.empty?
64
+
65
+ options = actions_to_keep.extract_options!
66
+ actions_to_remove = Array(options[:except])
67
+ actions_to_remove += ACTIONS - actions_to_keep.map { |a| a.to_sym } unless actions_to_keep.first == :all
68
+ actions_to_remove.map! { |a| a.to_sym }.uniq!
69
+ (instance_methods.map { |m| m.to_sym } & actions_to_remove).each do |action|
70
+ undef_method action, "#{action}!"
71
+ end
72
+ end
73
+
74
+ # Detects params from url and apply as scopes to your classes.
75
+ #
76
+ # Your model:
77
+ #
78
+ # class Graduation < ActiveRecord::Base
79
+ # named_scope :featured, :conditions => { :featured => true }
80
+ # named_scope :by_degree, proc {|degree| { :conditions => { :degree => degree } } }
81
+ # end
82
+ #
83
+ # Your controller:
84
+ #
85
+ # class GraduationsController < InheritedResources::Base
86
+ # has_scope :featured, :boolean => true, :only => :index
87
+ # has_scope :by_degree, :only => :index
88
+ # end
89
+ #
90
+ # Then for each request:
91
+ #
92
+ # /graduations
93
+ # #=> acts like a normal request
94
+ #
95
+ # /graduations?featured=true
96
+ # #=> calls the named scope and bring featured graduations
97
+ #
98
+ # /graduations?featured=true&by_degree=phd
99
+ # #=> brings featured graduations with phd degree
100
+ #
101
+ # You can retrieve the current scopes in use with <tt>current_scopes</tt>
102
+ # method. In the last case, it would return: { :featured => "true", :by_degree => "phd" }
103
+ #
104
+ # == Options
105
+ #
106
+ # * <tt>:boolean</tt> - When set to true, call the scope only when the param is true or 1,
107
+ # and does not send the value as argument.
108
+ #
109
+ # * <tt>:only</tt> - In which actions the scope is applied. By default is :all.
110
+ #
111
+ # * <tt>:except</tt> - In which actions the scope is not applied. By default is :none.
112
+ #
113
+ # * <tt>:as</tt> - The key in the params hash expected to find the scope.
114
+ # Defaults to the scope name.
115
+ #
116
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
117
+ # if the scope should apply
118
+ #
119
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
120
+ # if the scope should NOT apply.
121
+ #
122
+ # * <tt>:default</tt> - Default value for the scope. Whenever supplied the scope
123
+ # is always called. This is useful to add easy pagination.
124
+ #
125
+ def has_scope(*scopes)
126
+ options = scopes.extract_options!
127
+
128
+ options.symbolize_keys!
129
+ options.assert_valid_keys(:boolean, :key, :only, :except,
130
+ :if, :unless, :default, :as)
131
+
132
+ if options[:key]
133
+ ActiveSupport::Deprecation.warn "has_scope :key is deprecated, use :as instead"
134
+ options[:as] ||= options[:key]
135
+ end
136
+
137
+ if self.scopes_configuration.empty?
138
+ include HasScopeHelpers
139
+ helper_method :current_scopes
140
+ end
141
+
142
+ scopes.each do |scope|
143
+ self.scopes_configuration[scope] ||= {}
144
+ self.scopes_configuration[scope][:as] = options[:as] || scope
145
+ self.scopes_configuration[scope][:only] = Array(options[:only])
146
+ self.scopes_configuration[scope][:except] = Array(options[:except])
147
+
148
+ [:if, :unless, :boolean, :default].each do |opt|
149
+ self.scopes_configuration[scope][opt] = options[opt] if options.key?(opt)
150
+ end
151
+ end
152
+ end
153
+
154
+ # Defines that this controller belongs to another resource.
155
+ #
156
+ # belongs_to :projects
157
+ #
158
+ # == Options
159
+ #
160
+ # * <tt>:parent_class</tt> - Allows you to specify what is the parent class.
161
+ #
162
+ # belongs_to :project, :parent_class => AdminProject
163
+ #
164
+ # * <tt>:class_name</tt> - Also allows you to specify the parent class, but you should
165
+ # give a string. Added for ActiveRecord belongs to compatibility.
166
+ #
167
+ # * <tt>:instance_name</tt> - The instance variable name. By default is the name of the association.
168
+ #
169
+ # belongs_to :project, :instance_name => :my_project
170
+ #
171
+ # * <tt>:finder</tt> - Specifies which method should be called to instantiate the parent.
172
+ #
173
+ # belongs_to :project, :finder => :find_by_title!
174
+ #
175
+ # This will make your projects be instantiated as:
176
+ #
177
+ # Project.find_by_title!(params[:project_id])
178
+ #
179
+ # Instead of:
180
+ #
181
+ # Project.find(params[:project_id])
182
+ #
183
+ # * <tt>:param</tt> - Allows you to specify params key to retrieve the id.
184
+ # Default is :association_id, which in this case is :project_id.
185
+ #
186
+ # * <tt>:route_name</tt> - Allows you to specify what is the route name in your url
187
+ # helper. By default is association name.
188
+ #
189
+ # * <tt>:collection_name</tt> - Tell how to retrieve the next collection. Let's
190
+ # suppose you have Tasks which belongs to Projects
191
+ # which belongs to companies. This will do somewhere
192
+ # down the road:
193
+ #
194
+ # @company.projects
195
+ #
196
+ # But if you want to retrieve instead:
197
+ #
198
+ # @company.admin_projects
199
+ #
200
+ # You supply the collection name.
201
+ #
202
+ # * <tt>:polymorphic</tt> - Tell the association is polymorphic.
203
+ #
204
+ # * <tt>:singleton</tt> - Tell it's a singleton association.
205
+ #
206
+ # * <tt>:optional</tt> - Tell the association is optional (it's a special
207
+ # type of polymorphic association)
208
+ #
209
+ def belongs_to(*symbols, &block)
210
+ options = symbols.extract_options!
211
+
212
+ options.symbolize_keys!
213
+ options.assert_valid_keys(:class_name, :parent_class, :instance_name, :param,
214
+ :finder, :route_name, :collection_name, :singleton,
215
+ :polymorphic, :optional)
216
+
217
+ optional = options.delete(:optional)
218
+ singleton = options.delete(:singleton)
219
+ polymorphic = options.delete(:polymorphic)
220
+ finder = options.delete(:finder)
221
+
222
+ include BelongsToHelpers if self.parents_symbols.empty?
223
+
224
+ acts_as_singleton! if singleton
225
+ acts_as_polymorphic! if polymorphic || optional
226
+
227
+ raise ArgumentError, 'You have to give me at least one association name.' if symbols.empty?
228
+ raise ArgumentError, 'You cannot define multiple associations with options: #{options.keys.inspect} to belongs to.' unless symbols.size == 1 || options.empty?
229
+
230
+ symbols.each do |symbol|
231
+ symbol = symbol.to_sym
232
+
233
+ if polymorphic || optional
234
+ self.parents_symbols << :polymorphic unless self.parents_symbols.include?(:polymorphic)
235
+ self.resources_configuration[:polymorphic][:symbols] << symbol
236
+ self.resources_configuration[:polymorphic][:optional] ||= optional
237
+ else
238
+ self.parents_symbols << symbol
239
+ end
240
+
241
+ config = self.resources_configuration[symbol] = {}
242
+ config[:parent_class] = options.delete(:parent_class)
243
+ config[:parent_class] ||= (options.delete(:class_name) || symbol).to_s.pluralize.classify.constantize rescue nil
244
+ config[:collection_name] = options.delete(:collection_name) || symbol.to_s.pluralize.to_sym
245
+ config[:instance_name] = options.delete(:instance_name) || symbol
246
+ config[:param] = options.delete(:param) || :"#{symbol}_id"
247
+ config[:route_name] = options.delete(:route_name) || symbol
248
+ config[:finder] = finder || :find
249
+ end
250
+
251
+ if block_given?
252
+ class_eval(&block)
253
+ else
254
+ create_resources_url_helpers!
255
+ end
256
+ end
257
+ alias :nested_belongs_to :belongs_to
258
+
259
+ # A quick method to declare polymorphic belongs to.
260
+ #
261
+ def polymorphic_belongs_to(*symbols, &block)
262
+ options = symbols.extract_options!
263
+ options.merge!(:polymorphic => true)
264
+ belongs_to(*symbols << options, &block)
265
+ end
266
+
267
+ # A quick method to declare singleton belongs to.
268
+ #
269
+ def singleton_belongs_to(*symbols, &block)
270
+ options = symbols.extract_options!
271
+ options.merge!(:singleton => true)
272
+ belongs_to(*symbols << options, &block)
273
+ end
274
+
275
+ # A quick method to declare optional belongs to.
276
+ #
277
+ def optional_belongs_to(*symbols, &block)
278
+ options = symbols.extract_options!
279
+ options.merge!(:optional => true)
280
+ belongs_to(*symbols << options, &block)
281
+ end
282
+
283
+ private
284
+
285
+ def acts_as_singleton! #:nodoc:
286
+ unless self.resources_configuration[:self][:singleton]
287
+ self.resources_configuration[:self][:singleton] = true
288
+ include SingletonHelpers
289
+ actions :all, :except => :index
290
+ end
291
+ end
292
+
293
+ def acts_as_polymorphic! #:nodoc:
294
+ unless self.parents_symbols.include?(:polymorphic)
295
+ include PolymorphicHelpers
296
+ helper_method :parent, :parent_type, :parent_class, :parent?
297
+ end
298
+ end
299
+
300
+ # Initialize resources class accessors and set their default values.
301
+ #
302
+ def initialize_resources_class_accessors! #:nodoc:
303
+ # Initialize resource class
304
+ self.resource_class = begin
305
+ self.controller_name.classify.constantize
306
+ rescue NameError
307
+ nil
308
+ end
309
+
310
+ # Initialize resources configuration hash
311
+ self.resources_configuration ||= {}
312
+ config = self.resources_configuration[:self] = {}
313
+ config[:collection_name] = self.controller_name.to_sym
314
+ config[:instance_name] = self.controller_name.singularize.to_sym
315
+
316
+ config[:route_collection_name] = config[:collection_name]
317
+ config[:route_instance_name] = config[:instance_name]
318
+
319
+ # Deal with namespaced controllers
320
+ namespaces = self.controller_path.split('/')[0..-2]
321
+ config[:route_prefix] = namespaces.join('_') unless namespaces.empty?
322
+
323
+ # Initialize polymorphic, singleton, scopes and belongs_to parameters
324
+ self.parents_symbols ||= []
325
+ self.scopes_configuration ||= {}
326
+ self.resources_configuration[:polymorphic] ||= { :symbols => [], :optional => false }
327
+ end
328
+
329
+ # Hook called on inheritance.
330
+ #
331
+ def inherited(base) #:nodoc:
332
+ super(base)
333
+ base.send :initialize_resources_class_accessors!
334
+ base.send :create_resources_url_helpers!
335
+ end
336
+
337
+ end
338
+ end
@@ -0,0 +1,26 @@
1
+ module InheritedResources
2
+ # Allows controllers to write actions using a class method DSL.
3
+ #
4
+ # class MyController < InheritedResources::Base
5
+ # create! do |success, failure|
6
+ # success.html { render :text => "It works!" }
7
+ # end
8
+ # end
9
+ #
10
+ module DSL
11
+ def self.included(base)
12
+ ACTIONS.each do |action|
13
+ base.class_eval <<-WRITTER
14
+ def self.#{action}!(options={}, &block)
15
+ define_method :__#{action}, &block
16
+ class_eval <<-ACTION
17
+ def #{action}
18
+ super(\#{options.inspect}, &method(:__#{action}))
19
+ end
20
+ ACTION
21
+ end
22
+ WRITTER
23
+ end
24
+ end
25
+ end
26
+ end