inherited_resources 0.9.5 → 1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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