# Change default method mappings?

**URL:** <https://www.ruby-forum.com/t/change-default-method-mappings/181436>\
**Category:** Rails\
**Created:** [January 12, 2010, 1:03am UTC](https://www.ruby-forum.com/t/change-default-method-mappings/181436 "2010-01-12T01:03:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![AJ\_ONeal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@AJ\_ONeal](https://www.ruby-forum.com/u/AJ_ONeal)\
**Post date:** [January 12, 2010, 1:03am UTC](https://www.ruby-forum.com/t/change-default-method-mappings/181436/1 "2010-01-12T01:03:59Z")

</div>

Currently these mappings are established somewhere, but I haven’t found  
it  
:get =\> ‘index’, ‘show’  
:post =\> ‘create’  
:delete =\> ‘destroy’  
:put =\> ‘edit’

In particular I want to add  
:options =\> ‘options’

AJ ONeal

---

<div class="post-metadata">

**Author:** ![AJ\_ONeal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@AJ\_ONeal](https://www.ruby-forum.com/u/AJ_ONeal)\
**Post date:** [January 12, 2010, 2:05am UTC](https://www.ruby-forum.com/t/change-default-method-mappings/181436/2 "2010-01-12T02:05:38Z")

</div>

AJ ONeal wrote:

> Currently these mappings are established somewhere, but I haven’t found  
> it  
> :get =\> ‘index’, ‘show’  
> :post =\> ‘create’  
> :delete =\> ‘destroy’  
> :put =\> ‘edit’
> 
> In particular I want to add  
> :options =\> ‘options’

No you don’t. You probably want :get =\> ‘options’.

Here and in your other post, you’re confusing HTTP methods with Rails  
controller methods. I suggest rereading the routing guide.

> AJ ONeal

Best,  
–Â  
Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![AJ\_ONeal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@AJ\_ONeal](https://www.ruby-forum.com/u/AJ_ONeal)\
**Post date:** [January 12, 2010, 9:49pm UTC](https://www.ruby-forum.com/t/change-default-method-mappings/181436/3 "2010-01-12T21:49:00Z")

</div>

> No you don’t. Â You probably want :get =\> ‘options’.  
> Ah, but, I do!

> Here and in your other post, you’re confusing HTTP methods with Rails  
> controller methods.

Ah, but I’m not

Firefox and Safari / Chrome pre-flight CORS / XHR2 requests with  
OPTIONS before GET/POST/PUT/DELETE to see if the server allows CORS  
before attempting the request.  
Internet Explorer, I believe, just uses the HTTP vars from the  
original request.

XHR2 Headers such as  
X-Requested-With  
X-HTTP-Method-Override  
Content-Type  
Accept  
must be pre-approved with OPTIONS or the request will fail.

AJ ONeal

---

<div class="post-metadata">

**Author:** ![AJ\_ONeal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@AJ\_ONeal](https://www.ruby-forum.com/u/AJ_ONeal)\
**Post date:** [January 13, 2010, 12:57pm UTC](https://www.ruby-forum.com/t/change-default-method-mappings/181436/4 "2010-01-13T12:57:21Z")

</div>

On Jan 12, 8:47Â pm, CoolAJ86 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Firefox and Safari / Chrome pre-flight CORS / XHR2 requests with  
> OPTIONS before GET/POST/PUT/DELETE to see if the server allows CORS  
> before attempting the request.  
> Internet Explorer, I believe, just uses the HTTP vars from the  
> original request.

Make sense. Does :options =\> ‘options’ not work at all or are you just  
getting tired of typing it over and over again ? The former seems  
unlikely, but I haven’t tried. If just the latter then with\_options  
might be of use. You could also try overriding  
map\_default\_collection\_actions on AC::Resources::Resource

Fred

---

<div class="post-metadata">

**Author:** ![AJ\_ONeal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@AJ\_ONeal](https://www.ruby-forum.com/u/AJ_ONeal)\
**Post date:** [January 15, 2010, 8:47pm UTC](https://www.ruby-forum.com/t/change-default-method-mappings/181436/5 "2010-01-15T20:47:00Z")

</div>

> Make sense. Does :options =\> ‘options’ not work at all or are you just  
> getting tired of typing it over and over again ? The former seems  
> unlikely, but I haven’t tried. If just the latter then with\_options  
> might be of use. You could also try overriding  
> map\_default\_collection\_actions on AC::Resources::Resource
> 
> Fred

Thanks Fred,

Here’s the monkey patch for Rails 2.3.3. I imagine it should be easy  
to modify for other versions:

module ActionController  
module Resources  
class Resource #:nodoc:  
DEFAULT\_ACTIONS  
= :index, :create, :new, :edit, :show, :update, :destroy, :options  
#Options Patch  
end

```
private
  def map_member_actions(map, resource)
    resource.member_methods.each do |method, actions|
      actions.each do |action|
        [method].flatten.each do |m|
          action_path = resource.options[:path_names][action] if

```

resource.options[:path\_names].is\_a?(Hash)  
action\_path ||= Base.resources\_path\_names[action] ||  
action

```
          map_resource_routes(map, resource, action, "#

```

{resource.member\_path}#{resource.action\_separator}#{action\_path}", “#  
{action}\_#{resource.shallow\_name\_prefix}#{resource.singular}”, m,  
{ :force\_id =\> true })  
end  
end  
end

```
    route_path = "#{resource.shallow_name_prefix}#

```

{resource.singular}"  
map\_resource\_routes(map, resource, :show,  
resource.member\_path, route\_path)  
map\_resource\_routes(map, resource, :update,  
resource.member\_path, route\_path)  
map\_resource\_routes(map, resource, :destroy,  
resource.member\_path, route\_path)  
map\_resource\_routes(map, resource, :options, resource.path,  
route\_path) #Options Patch  
end

```
  def action_options_for(action, resource, method = nil,

```

resource\_options = {})  
default\_options = { :action =\> action.to\_s }  
require\_id = !resource.kind\_of?(SingletonResource)  
force\_id = resource\_options[:force\_id] && !resource.kind\_of?  
(SingletonResource)

```
    case default_options[:action]
      when "index", "new"; default_options.merge(add_conditions_for

```

(resource.conditions, method || :get)).merge(resource.requirements)  
when “create”; default\_options.merge(add\_conditions\_for  
(resource.conditions, method || :post)).merge(resource.requirements)  
when “show”, “edit”; default\_options.merge(add\_conditions\_for  
(resource.conditions, method || :get)).merge(resource.requirements  
(require\_id))  
when “update”; default\_options.merge(add\_conditions\_for  
(resource.conditions, method || :put)).merge(resource.requirements  
(require\_id))  
when “destroy”; default\_options.merge(add\_conditions\_for  
(resource.conditions, method || :delete)).merge(resource.requirements  
(require\_id))  
when “options”; default\_options.merge(add\_conditions\_for  
(resource.conditions, method || :options)).merge  
(resource.requirements) #Options Patch  
else default\_options.merge(add\_conditions\_for  
(resource.conditions, method)).merge(resource.requirements(force\_id))  
end  
end  
end  
end

On ubuntu the original file is found at:  
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action\_controller/  
resources.rb

And the patch should be placed in your Rails project folder in  
./lib/resources.rb

Once installed you can specify options on a per-controller basis like  
so:

app/controllers/guest\_sessions\_controller.rb:

# Create a session for non-logged in users which may be merged on

login or remain anonymous, one-time use.  
def create  
#TODO how to handle this in the case of internationalization  
# I chose not to put this in the db layer because this is shared  
with the user class  
guest = Guest.new({:display\_name=\>‘Guest’})  
guest.save  
guest\_session = GuestSession.new(guest)  
# sanitize the outbound hash now to keep it dry when we add xml  
and html support in addition to json  
hash = {:display\_name =\> guest.display\_name, :single\_access\_token  
=\> guest.single\_access\_token}  
respond\_to do |format|  
# TODO use client ACCEPT headers rather than .:format. That’s  
why we have HTTP standards.  
format.json { render :json =\> hash, :callback =\> params  
[:callback] }  
end  
end

# Log out

def destroy  
#TODO if the guest didn’t leave an e-mail, delete the guest  
(regarding as spam)  
current\_guest\_session.destroy  
message = {:message =\> “Logout successful!”, :errors =\> []}  
respond\_to do |format|  
format.json { render :json =\> message, :callback =\> params  
[:callback] }  
end  
end

# Show HTTP OPTIONS for XHR2 / CORS requests

def options  
render :nothing =\> true, :status =\> 204  
response.headers[‘Access-Control-Allow-Origin’] = ‘\*’  
response.headers[‘Access-Control-Allow-Methods’] = ‘POST, GET,  
PUT, DELETE, OPTIONS’  
response.headers[‘Access-Control-Allow-Credentials’] = ‘true’  
response.headers[‘Access-Control-Max-Age’] = ‘86400’ # 24 hours  
response.headers[‘Access-Control-Allow-Headers’] = ‘X-Requested-  
With, X-HTTP-Method-Override, Content-Type, Accept’  
end

Just to throw out some keyword for my fellow Googlers:  
You need this patch for Microsoft Discovery Protocol, WebDAV, DAV,  
XHR2, XDR (Cross-Domain Request) and CORS to work with Ruby on Rails  
for Firefox 3.5+, Chrome 4+, Safari 4+, and IE8+
