# How do I make this controller RESTful?

**URL:** <https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005>\
**Category:** Rails\
**Created:** [April 23, 2008, 12:47pm UTC](https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005 "2008-04-23T12:47:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rubienubie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rubienubie](https://www.ruby-forum.com/u/Rubienubie)\
**Post date:** [April 23, 2008, 12:47pm UTC](https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005/1 "2008-04-23T12:47:08Z")

</div>

Hello,

I’m trying to make this controller RESTful, but its post method uses  
two other methods – select\_category and show\_form – see them in  
action at [http://demo.chuckslist.org/ads/post](http://demo.chuckslist.org/ads/post). How do I reduce all of  
this to just one method? Other advice on making this controller as  
RESTful and beautiful as possible would ofcourse be much obliged.  
Here’s the controller:

class AdsController \< ApplicationController  
def show  
@ad = Ad.find\_by\_id(params[:id])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
end  
end  
def destroy  
if request.post?  
@ad = Ad.find\_by\_activation\_code(params[:id])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
else  
@ad.destroy  
flash[:notice] = “ad removed”  
redirect\_to root\_path  
end  
end  
end  
def list  
@category = Category.find\_by\_slug(params[:slug])  
if @category  
@ads = @category.ads.all\_active  
@requested\_category = @category.name + ’ in ’ +  
@category.parent\_category.name  
else  
@category = ParentCategory.find\_by\_slug(params[:slug])  
if @category  
@ads = @category.all\_ads  
@requested\_category = @category.name  
else  
flash[:warning] = “invalid request”  
redirect\_to root\_path  
end  
end  
end  
def post  
@parents = ParentCategory.find :all, :order =\> ‘name ASC’  
end  
def select\_category  
@parent\_category = ParentCategory.find\_by\_id(params[:id])  
end  
def show\_form  
@category = Category.find\_by\_id(params[:id])  
end  
def new  
if (params[:email] != params[:email\_confirmation])  
flash[:warning] = “e-mails don’t match”  
redirect\_to :controller =\> ‘ads’, :action =\> ‘post’  
else  
@author = Author.find\_by\_email(params[:email])  
if @author.blank?  
@author = Author.new  
@author.email = params[:email]  
@author.ip = request.env[‘REMOTE\_ADDR’]  
@author.save  
end  
@ad = Category.find\_by\_id(params[:category]).ads.new  
@ad.title = params[:title]  
@ad.ad = params[:ad].gsub(“\n”, “  
”)  
@ad.expiration = Time.now + 30.days  
@ad.author = @author  
@ad.author\_ip = request.env[‘REMOTE\_ADDR’]  
@ad.save  
@ad.handle\_images(params[“image\_attachments”])  
Mail.deliver\_activation(@ad, @author.email)  
flash[:notice] = “ad pending activation”  
end  
end  
def activate\_ad  
@ad = Ad.find\_by\_activation\_code(params[:activation\_code])  
if (@ad.nil?)  
flash[:warning] = “error activating ad”  
redirect\_to root\_path  
else  
if @ad.activate\_ad(params[:activation\_code])  
flash[:notice] = “ad activated”  
Mail.deliver\_activated(@ad, @ad.author.email)  
redirect\_to :action =\> ‘edit’, :activation\_code =\>  
@ad.activation\_code  
else  
flash[:warning] = “error activating ad”  
redirect\_to root\_path  
end  
end  
end  
def manage  
@ad = Ad.find\_by\_activation\_code(params[:activation\_code])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
else  
end  
end  
def edit  
@ad = Ad.find\_by\_activation\_code(params[:activation\_code])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
else  
end  
end  
def update  
@ad = Ad.find\_by\_activation\_code(params[:activation\_code])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
else  
@ad.ad = params[:ad].gsub(“\n”, “  
”)  
@ad.title = params[:title]  
if @ad.save  
@ad.handle\_images(params[“image\_attachments”])  
flash[:notice] = “ad updated”  
else  
flash[:warning] = “error updating ad”  
end  
redirect\_to :controller =\> ‘ads’, :action =\>  
‘manage’, :activation\_code =\> @ad.activation\_code  
end  
end  
def feed  
@ads = Ad.all\_active  
respond\_to do |format|  
format.rss { render :layout =\> false }  
format.atom # index.atom.builder  
end  
end  
end

Take care!

– Rubienubie

---

<div class="post-metadata">

**Author:** ![Rubienubie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rubienubie](https://www.ruby-forum.com/u/Rubienubie)\
**Post date:** [April 24, 2008, 12:55pm UTC](https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005/2 "2008-04-24T12:55:18Z")

</div>

Can somebody please help me?

So far I’ve moved show\_category and edit\_form into my ad model, and  
edited ads\_controller.rb to look like this:

class AdsController \< ApplicationController  
def index  
@category = Category.find\_by\_slug(params[:slug])  
if @category  
@ads = @category.ads.all\_active  
@requested\_category = @category.name + ’ in ’ +  
@category.parent\_category.name  
else  
@category = ParentCategory.find\_by\_slug(params[:slug])  
if @category  
@ads = @category.all\_ads  
@requested\_category = @category.name  
else  
flash[:warning] = “invalid request”  
redirect\_to root\_path  
end  
end  
end  
def show  
@ad = Ad.find\_by\_id(params[:id])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
end  
end  
def create  
@parents = ParentCategory.find :all, :order =\> ‘name ASC’  
end  
def new  
if (params[:email] != params[:email\_confirmation])  
flash[:warning] = “e-mails don’t match”  
redirect\_to create\_ads\_path  
else  
@author = Author.find\_by\_email(params[:email])  
if @author.blank?  
@author = Author.new  
@author.email = params[:email]  
@author.ip = request.env[‘REMOTE\_ADDR’]  
@author.save  
end  
@ad = Category.find\_by\_id(params[:category]).ads.new  
@ad.title = params[:title]  
@ad.ad = params[:ad].gsub("\n", “  
”)  
@ad.expiration = Time.now + 30.days  
@ad.author = @author  
@ad.author\_ip = request.env[‘REMOTE\_ADDR’]  
@ad.save  
@ad.handle\_images(params[“image\_attachments”])  
Mail.deliver\_activation(@ad, @author.email)  
flash[:notice] = “ad pending activation”  
end  
end  
def edit  
@ad = Ad.find\_by\_activation\_code(params[:activation\_code])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
else  
end  
end  
def update  
@ad = Ad.find\_by\_activation\_code(params[:activation\_code])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
else  
@ad.ad = params[:ad].gsub("\n", “  
”)  
@ad.title = params[:title]  
if @ad.save  
@ad.handle\_images(params[“image\_attachments”])  
flash[:notice] = “ad updated”  
else  
flash[:warning] = “error updating ad”  
end  
redirect\_to edit\_ads\_path, :activation\_code =\>  
@ad.activation\_code  
end  
end  
def destroy  
if request.post?  
@ad = Ad.find\_by\_activation\_code(params[:id])  
if (@ad.nil?)  
flash[:warning] = “ad doesn’t exist”  
redirect\_to root\_path  
else  
@ad.destroy  
flash[:notice] = “ad removed”  
redirect\_to root\_path  
end  
end  
end  
def feed  
@ads = Ad.all\_active  
respond\_to do |format|  
format.rss { render :layout =\> false }  
format.atom # index.atom.builder  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![Rubienubie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rubienubie](https://www.ruby-forum.com/u/Rubienubie)\
**Post date:** [April 25, 2008, 10:09am UTC](https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005/3 "2008-04-25T10:09:18Z")

</div>

I guess I’m on my own with this one.

---

<div class="post-metadata">

**Author:** ![Rubienubie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rubienubie](https://www.ruby-forum.com/u/Rubienubie)\
**Post date:** [April 25, 2008, 11:33am UTC](https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005/4 "2008-04-25T11:33:31Z")

</div>

Rubienubie wrote:

> I guess I’m on my own with this one.

sorry, but you must understand, that most people answering here are  
professional programmers with something like a working day. we jump in  
here once in a while and answer what we can. this may depend on our  
knowledge and on the question. not so many people will have the time to  
analyze that much code. especially not during the week. (so since it’s  
friday today tour chances are, somebody will do during weekend.  
otherwise keep your questions as short as possible and don’t expect  
people to jump for cosmetical cleanup stuff.

---

<div class="post-metadata">

**Author:** ![Rubienubie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rubienubie](https://www.ruby-forum.com/u/Rubienubie)\
**Post date:** [April 25, 2008, 3:47pm UTC](https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005/5 "2008-04-25T15:47:36Z")

</div>

@Thorsten: If you feel that way then just ignore it and move on. No  
reason to get ruffled by someone you’ll probably never meet.  
Moreover, the community as a whole is more likely to grow and evolve  
if we don’t eat our young. 🙂

@rubienubie:  
There seems to be a fundamental misunderstanding about REST at play  
here. Your first post in this thread suggests that you are worried  
about having more than one method that responds to an HTTP post but  
that is not a limiting factor. For simplicity we’ll say that a  
resource is an object that responds on a particular address. It’s  
response can be tailored based on two things: actions and the http  
verbs associated with those actions.

So, for your AdsController you’re actually dealing with _two_  
resources. One resource is the collection of ads and the other is an  
individual ad (really, many of these but one pattern to code). For  
the collection, then:

…/ads #address of the ads collection

can respond in different ways based on the HTTP verbs. Without  
qualification a GET maps to the index and a POST maps to create.

Similarly,

…/ads/1 # address of an individual ad

can respond in different ways. A PUT will #update it and a DELETE  
will #destroy it while a GET will #show it.

But you also get another degree of movement when you add actions. For  
example,

…/ads/1/do\_something

Could add as many as four different responses based on whether you do  
a GET, POST, PUT, or DELETE to that address. You’d map these in  
routes.rb like so:

map.resources :ads, :collection=\>{:do\_something\_else=\>_verb or  
any_}, :member=\>{:do\_something=\>_verb or any_}

So technically you could keep your controller very much the way it was  
and make it “RESTful”. Your refactoring is moving in a cleaner  
direction, though. One thing I’d add is to consider the “fat model,  
skinny controller” suggestion:  
[http://www.therailsway.com/2007/6/1/railsconf-recap-skinny-controllers](http://www.therailsway.com/2007/6/1/railsconf-recap-skinny-controllers).  
You’ve really got a lot of business logic tied up in your controllers  
that should not be there.

On Apr 25, 5:33 am, Thorsten M. \<rails-mailing-l…@andreas-

---

<div class="post-metadata">

**Author:** ![Rubienubie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rubienubie](https://www.ruby-forum.com/u/Rubienubie)\
**Post date:** [April 25, 2008, 4:05pm UTC](https://www.ruby-forum.com/t/how-do-i-make-this-controller-restful/226005/6 "2008-04-25T16:05:04Z")

</div>

@Andy: Oops, i hope nobody misunderstood my comment. it was not the  
intention to keep people from asking whatever they want or how long they  
want.  
i just wanted to give a tip, that clear and compact questions may get  
answered faster and others like this may take some time.  
(i think i answered quite some questions about “best practices” or more  
complicated issues myself.)

i didn’t want to criticize Rubienubie or the question.
