| Class | Resourceful::Builder |
| In: |
lib/resourceful/builder.rb
|
| Parent: | Object |
The Maker#make_resourceful block is evaluated in the context of an instance of this class. It provides various methods for customizing the behavior of the actions built by make_resourceful.
All instance methods of this class are available in the make_resourceful block.
| controller | [RW] | The klass of the controller on which the builder is working. |
The constructor is only meant to be called internally.
This takes the klass (class object) of a controller and constructs a Builder ready to apply the make_resourceful additions to the controller.
# File lib/resourceful/builder.rb, line 21
21: def initialize(kontroller)
22: @controller = kontroller
23: @action_module = Resourceful::Default::Actions.dup
24: @ok_actions = []
25: @callbacks = {:before => {}, :after => {}}
26: @responses = {}
27: @publish = {}
28: @parents = []
29: end
Adds the default RESTful actions to the controller.
If the only argument is :all, adds all the actions listed in Resourceful::ACTIONS (or Resourceful::SINGULAR_ACTIONS for a singular controller).
Otherwise, this adds all actions whose names were passed as arguments.
For example:
actions :show, :new, :create
This adds the show, new, and create actions to the controller.
The available actions are defined in Default::Actions.
# File lib/resourceful/builder.rb, line 81
81: def actions(*available_actions)
82: if available_actions.first == :all
83: available_actions = controller.new.plural? ? ACTIONS : SINGULAR_ACTIONS
84: end
85:
86: available_actions.each { |action| @ok_actions << action.to_sym }
87: end
Sets up a block of code to run after one or more events.
There are two sorts of after events. :create, :update, and :destroy are run after their respective database operations have been completed successfully. :create_fails, :update_fails, and :destroy_fails, on the other hand, are run after the database operations fail.
after events are run after the database operations but before any responses.
For example:
after :create_fails, :update_fails do
current_object.password = nil
end
This will nillify the password of the current object if the object creation/modification failed.
# File lib/resourceful/builder.rb, line 140
140: def after(*events, &block)
141: events.each do |event|
142: @callbacks[:after][event.to_sym] = block
143: end
144: end
This method is only meant to be called internally.
Applies all the changes that have been declared via the instance methods of this Builder to the kontroller passed in to the constructor.
# File lib/resourceful/builder.rb, line 36
36: def apply
37: apply_publish
38:
39: kontroller = @controller
40: Resourceful::ACTIONS.each do |action_named|
41: # See if this is a method listed by #actions
42: unless @ok_actions.include? action_named
43: # If its not listed, then remove the method
44: # No one can hit it... if its DEAD!
45: @action_module.send :remove_method, action_named
46: end
47: end
48:
49: kontroller.hidden_actions.reject! &@ok_actions.method(:include?)
50: kontroller.send :include, @action_module
51:
52: kontroller.read_inheritable_attribute(:resourceful_callbacks).merge! @callbacks
53: kontroller.read_inheritable_attribute(:resourceful_responses).merge! @responses
54:
55: kontroller.write_inheritable_attribute(:parents, @parents)
56: kontroller.before_filter { |c| c.send(:load_parent_objects) }
57: end
Sets up a block of code to run before one or more events.
All the default actions can be used as before events: :index, :show, :create, :update, :new, :edit, and :destroy.
before events are run after any objects are loaded, but before any database operations or responses.
For example:
before :show, :edit do
@page_title = current_object.title
end
This will set the @page_title variable to the current object’s title for the show and edit actions.
# File lib/resourceful/builder.rb, line 110
110: def before(*events, &block)
111: events.each do |event|
112: @callbacks[:before][event.to_sym] = block
113: end
114: end
Specifies a hierarchy of parent models for the current model. The array should be ordered as […, :great_grandparent, :grandparent, :parent]. Each parent’s object is automatically loaded into the proper instance variable (e.g. Person would be loaded into @person), and all child lookups are scoped so that they’re guaranteed to be children of the proper parent.
Note that the semantics of this function will likely change in the next release. Using it with only one parent is safe, but more than one will probably break in the future.
# File lib/resourceful/builder.rb, line 303
303: def belongs_to(*parents)
304: @parents = parents.map(&:to_s)
305: end
publish allows you to easily expose information about resourcess in a variety of formats. The formats parameter is a list of formats in which to publish the resources. The formats supported by default are xml, yaml, and json, but other formats may be added by defining to_format methods for the Array and Hash classes and registering the mime type with Rails’ Mime::Type.register. See Resourceful::Serialize for more details..
The :attributes option is mandatory. It takes an array of attributes (as symbols) to make public. These attributes can refer to any method on current_object; they aren’t limited to database fields. For example:
# posts_controller.rb publish :yaml, :attributes => [:title, :created_at, :rendered_content]
Then GET /posts/12.yaml would render
---
post:
title: Cool Stuff
rendered_content: |-
<p>This is a post.</p>
<p>It's about <strong>really</strong> cool stuff.</p>
created_at: 2007-04-28 04:32:08 -07:00
The :attributes array can even contain attributes that are themselves models. In this case, you must use a hash to specify their attributes as well. For example:
# person_controller.rb
publish :xml, :json, :attributes => [
:name, :favorite_color, {
:pet_cat => [:name, :breed],
:hat => [:type]
}]
Then GET /people/18.xml would render
<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>Nathan</name>
<favorite-color>blue</favorite_color>
<pet-cat>
<name>Jasmine</name>
<breed>panther</breed>
</pet-cat>
<hat>
<type>top</type>
</hat>
</person>
publish will also allow the index action to render lists of objects. An example would be too big, but play with it a little on your own to see.
publish takes only one optional option: only. This specifies which action to publish the resources for. By default, they’re published for both show and index. For example:
# cats_controller.rb publish :json, :only => :index, :attributes => [:name, :breed]
Then GET /cats.json would work, but GET /cats/294.json would fail.
# File lib/resourceful/builder.rb, line 275
275: def publish(*formats)
276: options = {
277: :only => [:show, :index]
278: }.merge(Hash === formats.last ? formats.pop : {})
279: raise "Must specify :attributes option" unless options[:attributes]
280:
281: Array(options.delete(:only)).each do |action|
282: @publish[action] ||= []
283: formats.each do |format|
284: format = format.to_sym
285: @publish[action] << [format, proc do
286: render_action = [:json, :xml].include?(format) ? format : :text
287: render render_action => (plural_action? ? current_objects : current_object).serialize(format, options)
288: end]
289: end
290: end
291: end
Sets up a block of code to run instead of the default responses for one or more events.
If the block takes a format parameter, it has the same semantics as Rails’ respond_to method. Various format methods are called on the format object with blocks that say what to do for each format. For example:
response_for :index do |format|
format.html
format.atom do
headers['Content-Type'] = 'application/atom+xml; charset=utf-8'
render :action => 'atom', :layout => false
end
end
This doesn’t do anything special for the HTML other than ensure that the proper view will be rendered, but for ATOM it sets the proper content type and renders the atom template.
If you only need to set the HTML response, you can omit the format parameter. For example:
response_for :new do
render :action => 'edit'
end
This is the same as
response_for :new do |format|
format.html { render :action => 'edit' }
end
The default responses are defined by Default::Responses.included.
# File lib/resourceful/builder.rb, line 188
188: def response_for(*actions, &block)
189: if block.arity < 1
190: response_for(*actions) do |format|
191: format.html(&block)
192: end
193: else
194: response = Response.new
195: block.call response
196:
197: actions.each do |action|
198: @responses[action.to_sym] = response.formats
199: end
200: end
201: end