inherited_resources 0.9.5 → 1.0.pre

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/CHANGELOG CHANGED
@@ -1,7 +1,12 @@
1
- # Version 0.9.4
1
+ * responders was removed from InheritedResources core and is a dependency. To install it, please do:
2
2
 
3
- * DEPRECATION: Use :success and :failure as flash messages instead :notice and :error
3
+ sudo gem install responders
4
4
 
5
+ * has_scope was removed from InheritedResources core and is now available as a standalone gem.
6
+ To install it, please do:
7
+
8
+ sudo gem install has_scope
9
+
5
10
  # Version 0.9
6
11
 
7
12
  * Allow dual blocks in destroy;
data/README.rdoc CHANGED
@@ -1,8 +1,4 @@
1
- Inherited Resources
2
- License: MIT
3
- Version: 0.9.2
4
-
5
- == Description
1
+ == Inherited Resources
6
2
 
7
3
  Inherited Resources speeds up development by making your controllers inherit
8
4
  all restful actions so you just have to focus on what is important. It makes
@@ -16,20 +12,53 @@ http://akitaonrails.com/2009/09/01/screencast-real-thin-restful-controllers-with
16
12
 
17
13
  Inherited Resources is tested and compatible with Rails 2.2.x and Rails 2.3.x.
18
14
 
19
- keywords: resources, controller, singleton, belongs_to, polymorphic, named_scope and I18n
20
-
21
15
  == Installation
22
16
 
23
- Install Inherited Resources is very easy. It is stored in GitHub, so just run
24
- the following:
17
+ Inherited Resources is available as gem on Gemcutter, so just run the following:
25
18
 
26
- gem sources -a http://gemcutter.org
27
19
  sudo gem install inherited_resources
28
20
 
29
21
  If you want it as plugin, just do:
30
22
 
31
23
  script/plugin install git://github.com/josevalim/inherited_resources.git
32
24
 
25
+ == Inherited Resources 1.0.pre
26
+
27
+ Inherited Resources is close to 1.0 version. A couple things changed,
28
+ so be sure to read the following sections if you want to try it out:
29
+
30
+ === HasScope
31
+
32
+ In Inherited Resources 1.0, has_scope is not part of its core anymore.
33
+ However, if you are using has_scope in your application, Inherited Resources
34
+ will handle all the required hooks automatically.
35
+
36
+ has_scope gem is available at:
37
+
38
+ http://github.com/plataformatec/has_scope
39
+
40
+ And can be installed as:
41
+
42
+ sudo gem install has_scope
43
+
44
+ === Responders
45
+
46
+ In Inherited Resources 1.0, responders are not part of its core anymore,
47
+ but is set as Inherited Resources dependency and it's used by default by
48
+ InheritedResources controllers. Be sure to check the documentation to see
49
+ how it will change your application:
50
+
51
+ http://github.com/plataformatec/responders
52
+
53
+ And it can be installed as:
54
+
55
+ sudo gem install responders
56
+
57
+ Using responders will set the flash message to :notice and :alert. You can change
58
+ that through the following configuration value:
59
+
60
+ InheritedResources.flash_keys = [ :success, :failure ]
61
+
33
62
  == Rspec known bug
34
63
 
35
64
  When used with integrate_views equals to false, rspec overwrites default_render,
@@ -246,109 +275,6 @@ And then you can rewrite the last example as:
246
275
  end
247
276
  end
248
277
 
249
- == Flash messages and I18n
250
-
251
- Flash messages are powered by I18n api. It checks for messages in the following
252
- order:
253
-
254
- flash.controller_name.action_name.status
255
- flash.actions.action_name.status
256
-
257
- If none is available, a default message in english set. In a create action
258
- on projects controller, it will search for:
259
-
260
- flash.projects.create.status
261
- flash.actions.create.status
262
-
263
- The status can be :notice (when the object can be created, updated
264
- or destroyed with success) or :error (when the objecy cannot be created
265
- or updated).
266
-
267
- Those messages are interpolated by using the resource class human name, which
268
- is also localized and it means you can set:
269
-
270
- flash:
271
- actions:
272
- create:
273
- notice: "Hooray! {{resource_name}} was successfully created!"
274
-
275
- It will replace {{resource_name}} by the human name of the resource class,
276
- which is "Project" in this case.
277
-
278
- But sometimes, flash messages are not that simple. Sometimes you want to say
279
- the title of the project while updating a project. Well, that's easy also:
280
-
281
- flash:
282
- projects:
283
- update:
284
- notice: "Hooray! The project "{{project_title}}" was updated!"
285
-
286
- Since :project_title is not available for interpolation by default, you have
287
- to overwrite interpolation_options.
288
-
289
- def interpolation_options
290
- { :project_title => @project.title }
291
- end
292
-
293
- Then you will finally have:
294
-
295
- "Hooray! The project "Plataforma" was updated!"
296
-
297
- By default, resource name is capitalized. If you want to make it lower case, you
298
- can add to your application controller:
299
-
300
- def interpolation_options
301
- { :resource_name => resource_class.human_name.downcase }
302
- end
303
-
304
- Finally, if your controller is namespaced, for example Admin::ProjectsController,
305
- the messages will be checked in the following order:
306
-
307
- flash.admin.projects.create.notice
308
- flash.admin.actions.create.notice
309
- flash.projects.create.notice
310
- flash.actions.create.notice
311
-
312
- == Has Scope
313
-
314
- InheritedResources tries to integrate nicely with your model. In order to do so,
315
- it also is named_scope fluent. Let's suppose our Project model with the scopes:
316
-
317
- class Project < ActiveRecord::Base
318
- named_scope :featured, :conditions => { :featured => true }
319
- named_scope :by_methodology, proc {|methodology| { :conditions => { :methodology => methodology } } }
320
- named_scope :limit, proc{|limit| :limit => limit.to_i }
321
- end
322
-
323
- Your controller:
324
-
325
- class ProjectsController < InheritedResources::Base
326
- has_scope :featured, :boolean => true, :only => :index
327
- has_scope :by_methodology
328
- has_scope :limit, :default => 10
329
- end
330
-
331
- Then for each request:
332
-
333
- /projects
334
- #=> acts like a normal request, but returning 10 projects
335
-
336
- /projects?featured=true
337
- #=> calls the featured named scope and bring 10 featured projects
338
-
339
- /projects?featured=true&by_methodology=agile&limit=20
340
- #=> brings 20 featured projects with methodology agile
341
-
342
- You can retrieve the current scopes in use with :current_scopes method.
343
- In the last case, it would return:
344
-
345
- { :featured => "true", :by_methodology => "agile", :limit => "20" }
346
-
347
- Finally, let's suppose you store on the session how many projects the user sees
348
- per page. In such cases, you can give a proc as default value:
349
-
350
- has_scope :limit, :default => proc{|c| c.session[:limit] || 10 }
351
-
352
278
  == Belongs to
353
279
 
354
280
  Finally, our Projects are going to get some Tasks. Then you create a
@@ -522,3 +448,4 @@ If you discover any bugs or want to drop a line, join us in the mailing list:
522
448
  http://groups.google.com/group/inherited_resources
523
449
 
524
450
  Copyright (c) 2009 José Valim http://blog.plataformatec.com.br
451
+ See the attached MIT License.
data/Rakefile CHANGED
@@ -16,7 +16,9 @@ begin
16
16
  s.homepage = "http://github.com/josevalim/inherited_resources"
17
17
  s.description = "Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important."
18
18
  s.authors = ['José Valim']
19
- s.files = FileList["[A-Z]*", "{lib}/**/*"]
19
+ s.files = FileList["[A-Z]*", "init.rb", "{lib}/**/*"]
20
+ s.add_dependency("responders", ">= 0.2")
21
+ s.add_dependency("has_scope", ">= 0.3")
20
22
  end
21
23
 
22
24
  Jeweler::GemcutterTasks.new
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'inherited_resources'
@@ -2,22 +2,31 @@
2
2
  # are loaded on demand.
3
3
  #
4
4
  unless defined?(ActionController::Responder)
5
- require File.join(File.dirname(__FILE__), 'inherited_resources', 'legacy', 'responder')
6
- require File.join(File.dirname(__FILE__), 'inherited_resources', 'legacy', 'respond_to')
5
+ require 'inherited_resources/legacy/responder'
6
+ require 'inherited_resources/legacy/respond_to'
7
7
  end
8
8
 
9
+ require 'responders'
10
+ I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'inherited_resources', 'locales', 'en.yml'))
11
+
9
12
  module InheritedResources
10
13
  ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ] unless self.const_defined?(:ACTIONS)
14
+
15
+ # Change the flash keys used by FlashResponder.
16
+ def self.flash_keys=(array)
17
+ Responders::FlashResponder.flash_keys = array
18
+ end
11
19
  end
12
20
 
13
21
  class ActionController::Base
22
+ public :flash, :render
23
+
14
24
  # If you cannot inherit from InheritedResources::Base you can call
15
25
  # inherit_resource in your controller to have all the required modules and
16
26
  # funcionality included.
17
- #
18
27
  def self.inherit_resources
19
28
  InheritedResources::Base.inherit_resources(self)
20
29
  initialize_resources_class_accessors!
21
30
  create_resources_url_helpers!
22
31
  end
23
- end
32
+ end
@@ -4,25 +4,25 @@ module InheritedResources
4
4
 
5
5
  # GET /resources
6
6
  def index(&block)
7
- respond_with(collection, &block)
7
+ respond_with(*with_chain(collection), &block)
8
8
  end
9
9
  alias :index! :index
10
10
 
11
11
  # GET /resources/1
12
12
  def show(&block)
13
- respond_with(resource, &block)
13
+ respond_with(*with_chain(resource), &block)
14
14
  end
15
15
  alias :show! :show
16
16
 
17
17
  # GET /resources/new
18
18
  def new(&block)
19
- respond_with(build_resource, &block)
19
+ respond_with(*with_chain(build_resource), &block)
20
20
  end
21
21
  alias :new! :new
22
22
 
23
23
  # GET /resources/1/edit
24
24
  def edit(&block)
25
- respond_with(resource, &block)
25
+ respond_with(*with_chain(resource), &block)
26
26
  end
27
27
  alias :edit! :edit
28
28
 
@@ -31,13 +31,10 @@ module InheritedResources
31
31
  object = build_resource
32
32
 
33
33
  if create_resource(object)
34
- set_flash_message!(:notice, '{{resource_name}} was successfully created.')
35
34
  options[:location] ||= resource_url rescue nil
36
- respond_with_dual_blocks(object, options, true, block)
37
- else
38
- set_flash_message!(:error)
39
- respond_with_dual_blocks(object, options, false, block)
40
35
  end
36
+
37
+ respond_with_dual_blocks(object, options, &block)
41
38
  end
42
39
  alias :create! :create
43
40
 
@@ -46,13 +43,10 @@ module InheritedResources
46
43
  object = resource
47
44
 
48
45
  if update_resource(object, params[resource_instance_name])
49
- set_flash_message!(:notice, '{{resource_name}} was successfully updated.')
50
46
  options[:location] ||= resource_url rescue nil
51
- respond_with_dual_blocks(object, options, true, block)
52
- else
53
- set_flash_message!(:error)
54
- respond_with_dual_blocks(object, options, false, block)
55
47
  end
48
+
49
+ respond_with_dual_blocks(object, options, &block)
56
50
  end
57
51
  alias :update! :update
58
52
 
@@ -61,19 +55,13 @@ module InheritedResources
61
55
  object = resource
62
56
  options[:location] ||= collection_url rescue nil
63
57
 
64
- if destroy_resource(object)
65
- set_flash_message!(:notice, '{{resource_name}} was successfully destroyed.')
66
- respond_with_dual_blocks(object, options, true, block)
67
- else
68
- set_flash_message!(:error, '{{resource_name}} could not be destroyed.')
69
- respond_with_dual_blocks(object, options, false, block)
70
- end
58
+ destroy_resource(object)
59
+ respond_with_dual_blocks(object, options, &block)
71
60
  end
72
61
  alias :destroy! :destroy
73
62
 
74
63
  # Make aliases protected
75
64
  protected :index!, :show!, :new!, :create!, :edit!, :update!, :destroy!
76
-
77
65
  end
78
66
  end
79
67
 
@@ -31,13 +31,14 @@ module InheritedResources
31
31
  base.with_options :instance_writer => false do |c|
32
32
  c.class_inheritable_accessor :resource_class
33
33
  c.class_inheritable_array :parents_symbols
34
- c.class_inheritable_hash :resources_configuration, :scopes_configuration
34
+ c.class_inheritable_hash :resources_configuration
35
35
  end
36
36
 
37
- protected :resource_class, :parents_symbols, :resources_configuration, :scopes_configuration
37
+ protected :resource_class, :parents_symbols, :resources_configuration
38
38
  end
39
39
  end
40
40
 
41
41
  inherit_resources(self)
42
+ self.responder = InheritedResources::Responder
42
43
  end
43
44
  end
@@ -1,5 +1,5 @@
1
1
  # Whenever base is required load the dumb responder since it's used inside actions.
2
- require File.dirname(__FILE__) + '/dumb_responder.rb'
2
+ require 'inherited_resources/blank_slate'
3
3
 
4
4
  module InheritedResources
5
5
  # Base helpers for InheritedResource work. Some methods here can be overwriten
@@ -138,6 +138,11 @@ module InheritedResources
138
138
 
139
139
  private
140
140
 
141
+ # Adds the given object to association chain.
142
+ def with_chain(object)
143
+ association_chain + [ object ]
144
+ end
145
+
141
146
  # Fast accessor to resource_collection_name
142
147
  #
143
148
  def resource_collection_name #:nodoc:
@@ -156,7 +161,7 @@ module InheritedResources
156
161
  def end_of_association_chain #:nodoc:
157
162
  if chain = association_chain.last
158
163
  if method_for_association_chain
159
- apply_scope_to(chain.send(method_for_association_chain))
164
+ apply_scopes_if_available(chain.send(method_for_association_chain))
160
165
  else
161
166
  # This only happens when we specify begin_of_association_chain in
162
167
  # a singletion controller without parents. In this case, the chain
@@ -165,7 +170,7 @@ module InheritedResources
165
170
  chain
166
171
  end
167
172
  else
168
- apply_scope_to(resource_class)
173
+ apply_scopes_if_available(resource_class)
169
174
  end
170
175
  end
171
176
 
@@ -214,98 +219,6 @@ module InheritedResources
214
219
  instance_variable_set("@#{resource_collection_name}", collection)
215
220
  end
216
221
 
217
- # Helper to set flash messages. It's powered by I18n API.
218
- # It checks for messages in the following order:
219
- #
220
- # flash.controller_name.action_name.status
221
- # flash.actions.action_name.status
222
- #
223
- # If none is available, a default message is set. So, if you have
224
- # a CarsController, create action, it will check for:
225
- #
226
- # flash.cars.create.status
227
- # flash.actions.create.status
228
- #
229
- # The statuses can be :notice (when the object can be created, updated
230
- # or destroyed with success) or :error (when the objecy cannot be created
231
- # or updated).
232
- #
233
- # Those messages are interpolated by using the resource class human name.
234
- # This means you can set:
235
- #
236
- # flash:
237
- # actions:
238
- # create:
239
- # notice: "Hooray! {{resource_name}} was successfully created!"
240
- #
241
- # But sometimes, flash messages are not that simple. Going back
242
- # to cars example, you might want to say the brand of the car when it's
243
- # updated. Well, that's easy also:
244
- #
245
- # flash:
246
- # cars:
247
- # update:
248
- # notice: "Hooray! You just tuned your {{car_brand}}!"
249
- #
250
- # Since :car_name is not available for interpolation by default, you have
251
- # to overwrite interpolation_options.
252
- #
253
- # def interpolation_options
254
- # { :car_brand => @car.brand }
255
- # end
256
- #
257
- # Then you will finally have:
258
- #
259
- # 'Hooray! You just tuned your Aston Martin!'
260
- #
261
- # If your controller is namespaced, for example Admin::CarsController,
262
- # the messages will be checked in the following order:
263
- #
264
- # flash.admin.cars.create.status
265
- # flash.admin.actions.create.status
266
- # flash.cars.create.status
267
- # flash.actions.create.status
268
- #
269
- def set_flash_message!(status, default_message=nil)
270
- return flash[status] = default_message unless defined?(::I18n)
271
-
272
- resource_name = if resource_class
273
- if resource_class.respond_to?(:human_name)
274
- resource_class.human_name
275
- else
276
- resource_class.name.underscore.humanize
277
- end
278
- else
279
- "Resource"
280
- end
281
-
282
- given_options = if self.respond_to?(:interpolation_options)
283
- interpolation_options
284
- else
285
- {}
286
- end
287
-
288
- options = {
289
- :default => default_message || '',
290
- :resource_name => resource_name
291
- }.merge(given_options)
292
-
293
- defaults = []
294
- slices = controller_path.split('/')
295
-
296
- while slices.size > 0
297
- defaults << :"flash.#{slices.fill(controller_name, -1).join('.')}.#{action_name}.#{status}"
298
- defaults << :"flash.#{slices.fill(:actions, -1).join('.')}.#{action_name}.#{status}"
299
- slices.shift
300
- end
301
-
302
- options[:default] = defaults.push(options[:default])
303
- options[:default].flatten!
304
-
305
- message = ::I18n.t options[:default].shift, options
306
- flash[status] = message unless message.blank?
307
- end
308
-
309
222
  # Used to allow to specify success and failure within just one block:
310
223
  #
311
224
  # def create
@@ -317,38 +230,32 @@ module InheritedResources
317
230
  # It also calculates the response url in case a block without arity is
318
231
  # given and returns it. Otherwise returns nil.
319
232
  #
320
- def respond_with_dual_blocks(object, options, success, given_block, &block) #:nodoc:
321
- case given_block.try(:arity)
233
+ def respond_with_dual_blocks(object, options, &block) #:nodoc:
234
+ args = (with_chain(object) << options)
235
+
236
+ case block.try(:arity)
322
237
  when 2
323
- respond_with(object, options) do |responder|
324
- dumb_responder = InheritedResources::DumbResponder.new
325
- if success
326
- given_block.call(responder, dumb_responder)
238
+ respond_with(*args) do |responder|
239
+ blank_slate = InheritedResources::BlankSlate.new
240
+ if object.errors.empty?
241
+ block.call(responder, blank_slate)
327
242
  else
328
- given_block.call(dumb_responder, responder)
243
+ block.call(blank_slate, responder)
329
244
  end
330
- block.try(:call, responder)
331
245
  end
332
246
  when 1
333
- if block
334
- respond_with(object, options) do |responder|
335
- given_block.call(responder)
336
- block.call(responder)
337
- end
338
- else
339
- respond_with(object, options, &given_block)
340
- end
247
+ respond_with(*args, &block)
341
248
  else
342
- options[:location] = given_block.call if given_block
343
- respond_with(object, options, &block)
249
+ options[:location] = block.call if block
250
+ respond_with(*args)
344
251
  end
345
252
  end
346
253
 
347
254
  # Hook to apply scopes. By default returns only the target_object given.
348
255
  # It's extend by HasScopeHelpers.
349
256
  #
350
- def apply_scope_to(target_object) #:nodoc:
351
- target_object
257
+ def apply_scopes_if_available(target_object) #:nodoc:
258
+ respond_to?(:apply_scopes) ? apply_scopes(target_object) : target_object
352
259
  end
353
260
 
354
261
  # Symbols chain in base helpers return nothing. This is later overwriten