# RESTful PUT and button\_to

**URL:** <https://www.ruby-forum.com/t/restful-put-and-button-to/86717>\
**Category:** Rails\
**Created:** [February 25, 2007, 12:02am UTC](https://www.ruby-forum.com/t/restful-put-and-button-to/86717 "2007-02-25T00:02:15Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![avdi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c6cbf5/32.png) [@avdi](https://www.ruby-forum.com/u/avdi)\
**Post date:** [February 25, 2007, 12:02am UTC](https://www.ruby-forum.com/t/restful-put-and-button-to/86717/1 "2007-02-25T00:02:15Z")

</div>

I’m working on a RESTful app, and I’ve hit a snag. Here’s a  
simplified example of the problem. (Excuse me if this example code  
isn’t strictly correct; I’m typing from memory.)

Suppose I have a table which models a simple counter. It has a single  
column, “count”:

class CreateCounters \< ActiveRecord::Migration  
def self.up  
create\_table :counters do |t|  
t.column :count, :integer  
end  
end

def self.down  
drop\_table :counters  
end

I’ve created a RESTful controller using the scaffold\_resource  
generator. In the “show” view, I’d like to put a link which  
increments the counter by one:

\<%= h @counter.content %\>  
\<%= button\_to “++”, ??? %\>

If this were a traditional rails app, the next step would be obvious.  
I’d add an “increment” action to the controller:

CounterController  
…  
def increment  
@counter = Counter.find(params[:id])  
@counter.count += 1  
@counter.save  
redirect\_to :action =\> “show”  
end  
end

And I’d link the action to the controller:

\<%= h @counter.content %\>  
\<%= button\_to “++”, :action =\> “increment” %\>

However, this isn’t RESTful. The REST way, as best I understand, is  
that updates to an existing resource are accomplished by PUTing an  
updated version of the resource to the resource’s path, as if the user  
had opened the “edit” view, manually incremented the count, and  
clicked “submit”.

And that’s where I get hung up. How do I create a link (or button) in  
the view which will call “update” in this way?

Here’s one attempt I made:

\<%= h @counter.content %\>  
\<%= button\_to “++”,  
counter\_path(  
:id =\> @counter,  
:counter =\> { :count =\> @counter.count + 1 } ),  
:method =\> :put %\>

But that’s wrong for two reasons. First, the counter\_path helper  
flattens the nested hash, so the for a counter with id 1 and  
count==42, the URL comes out like “/counters/1?count43” - which won’t  
be parsed correctly into the params hash by the “update” action.

Second, and more importantly, it’s not truly RESTful, because it’s  
PUTing to “/counters/1?count43”, not “/counters/1”.

As far as I can tell what I really need is a way to add extra hidden  
fields to the form that button\_to generates. But I can’t find any way  
to do that. And from my reading of the button\_to (and link\_to)  
source, there is no way to do this.

So: am I missing something? What’s the right way to do this? Do I  
have to construct the form and hidden fields manually, without the  
help of button\_to? Or is there another way to go about it entirely?

Thanks in advance,

–  
Avdi

---

<div class="post-metadata">

**Author:** ![avdi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c6cbf5/32.png) [@avdi](https://www.ruby-forum.com/u/avdi)\
**Post date:** [February 25, 2007, 4:58am UTC](https://www.ruby-forum.com/t/restful-put-and-button-to/86717/2 "2007-02-25T04:58:59Z")

</div>

Hi –

On Sun, 25 Feb 2007, Avdi G. wrote:

> create\_table :counters do |t|  
> increments the counter by one:  
> @counter = Counter.find(params[:id])
> 
> be parsed correctly into the params hash by the “update” action.  
> have to construct the form and hidden fields manually, without the  
> help of button\_to? Or is there another way to go about it entirely?

That’s an interesting question. It’s also a nice distillation of some  
REST-related issues.

I follow what you’re saying about the form fields, and normalizing the  
++ request so that it’s really just a specific case of the general  
“Reset this number” request where the number being reset to happens to  
be the current number plus one. My current thinking, though, is that  
if there is no general update process – that is, if PUT counters/:id  
always maps exactly to incrementing the counter by one and returning a  
representation of it in its new state, then that’s OK because it’s  
unambiguous. Even though the number count+1 does not reside in the  
representation in the request, I think, at least tentatively, that  
that doesn’t matter as long as the semantics of the resource and its  
identifiers give the system everything it needs to update the  
resource.

I’d even tend to think that it’s OK to have a default behavior in the  
update method – i.e., if params[:counter][:count] is absent, assume  
that it’s an increment of one. The reasoning here is partly that the  
form input is not, in any case, the resource itself; it’s just a way  
of telling the server what the resource should look like. So the  
absence of HTML form fields should not necessarily mean that, from a  
REST perspective, the request is uninterpretable.

Anyway, that’s my current train of thought. Back at ya’ 🙂

David

–  
Q. What is THE Ruby book for Rails developers?  
A. RUBY FOR RAILS by David A. Black ([http://www.manning.com/black](http://www.manning.com/black))  
(See what readers are saying! [http://www.rubypal.com/r4rrevs.pdf](http://www.rubypal.com/r4rrevs.pdf))  
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?  
A. Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![avdi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c6cbf5/32.png) [@avdi](https://www.ruby-forum.com/u/avdi)\
**Post date:** [February 25, 2007, 9:40am UTC](https://www.ruby-forum.com/t/restful-put-and-button-to/86717/3 "2007-02-25T09:40:41Z")

</div>

unknown wrote:

> I’d even tend to think that it’s OK to have a default behavior in the  
> update method – i.e., if params[:counter][:count] is absent, assume  
> that it’s an increment of one. The reasoning here is partly that the  
> form input is not, in any case, the resource itself; it’s just a way  
> of telling the server what the resource should look like. So the  
> absence of HTML form fields should not necessarily mean that, from a  
> REST perspective, the request is uninterpretable.

Thank you for your thoughts. I follow what you’re saying.  
Unfortunately for my purpose I’m not sure it helps. I chose the  
“counter” example because I thought it distilled the problem at hand  
without introducing any distracting factors; my actual app code is more  
complex than that. To put it briefly it involves nested topics in an  
outline, which need the ability to be indented or outdented with a  
single click. In this case there’s no default behaviour - the topic’s  
new parent topic depends on whether the user clicks to indent or  
outdent.

I guess I just need to manually generate the hidden form if I want to do  
it RESTfully. Thanks for confirming that this is a real issue, and not  
just something I was overlooking.

Cheers,

–  
Avdi
