Help me clean up UGLY code...

In my controller, I have the following:
  def method1
    displayList(:method1)
  end

  def method2
    displayList(:method2)
  end

  def method3
    displayList(:method3)
  end

  def method4
    displayList(:method4)
  end

  def method5
    displayList(:method5)
  end

This just strikes me as ugly....

Any suggestions on how to clean this up? (obviously I changed the
names to make it a more generic issue.)

Thanks,

Alan

%(method1 method2 method3).each do |m|
  define_method(m) do
    displayList(m)
  end
end

should do it. Or if it has to be a symbol, you can do

displayList(:"#{m}")

Jason

Please excuse my ignorance, but where in the controller do you put this code?

--Alan

Anywhere outside of a method. It's run when the class is loaded. Just
simple case of Ruby's meta programming.

Jason

Jason has kindly provided the “how” to do this, but I would question they “why” you are doing this?
What’s the need to have a bunch of methods that do nothing other than routing to another method? Maybe there should be one dispatching methods that calls the others?

just a thought,
/Shawn

What I am trying to do is have multiple ways of looking at "slices" of the data.

For example:
site/inbox -> Shows only items in the "inbox" state
site/state1 -> Shows items in the "state1" state
site/state2 -> Shows items in the "state2" state

Would you recommend another way of doing this?

--Alan

I don't know if this would be "recommended" -- I'm new here too :slight_smile: --
but you could certainly dry it up easily with 'method_missing'.

FWIW,

why not have a show state method which takes as a parameter the state to show ?

Fred

create a new route that makes that bit be a parameter:

in config/routes.rb:
   map.connect 'site/:state', :controller => 'alan', :action => :displayList

class AlanController
   def displayList
     @items = Item.find(:all, :conditions => { :state => params[:state] })
   end
end

If you can make a generic example, I can respond with generic code, right?

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

Rob,
  That looks pretty close. I definitely do NOT understand the routing
magic well enough. I guess I put this later so that other areas like
site/login and site/dashboard, would not be interpreted under this.

Thanks,

Alan

Thanks Rob,
That was more of what I was trying to get across. that the states themselves are/should be parameters.

/Shawn

Here is how I ended up solving it (thanks to everyone)
In routes.rb
<code>
  map.inbox '/inbox', :controller => 'tasks', :action =>
'task_list', :state =>'inbox'
  map.actions '/actions', :controller => 'tasks', :action =>
'task_list', :state =>'actions'
  map.waiting '/waiting', :controller => 'tasks', :action =>
'task_list', :state =>'waiting'
  map.someday '/someday', :controller => 'tasks', :action =>
'task_list', :state =>'someday'
  map.ticklers '/ticklers', :controller => 'tasks', :action =>
'task_list', :state =>'ticklers'
  map.reference '/reference', :controller => 'tasks', :action =>
'task_list', :state =>'reference'
</code>

In tasks_controller.rb, there is a task_list method

Thanks again to everyone for your help!!

--Alan

Here is how I ended up solving it (thanks to everyone)
In routes.rb
<code>
map.inbox '/inbox', :controller => 'tasks', :action =>
'task_list', :state =>'inbox'
map.actions '/actions', :controller => 'tasks', :action =>
'task_list', :state =>'actions'
map.waiting '/waiting', :controller => 'tasks', :action =>
'task_list', :state =>'waiting'
map.someday '/someday', :controller => 'tasks', :action =>
'task_list', :state =>'someday'
map.ticklers '/ticklers', :controller => 'tasks', :action =>
'task_list', :state =>'ticklers'
map.reference '/reference', :controller => 'tasks', :action =>
'task_list', :state =>'reference'
</code>

In tasks_controller.rb, there is a task_list method

Thanks again to everyone for your help!!

--Alan

A bit simpler as:

  map.with_options :controller => 'tasks', :action =>'task_list' do |tasks>
    tasks.inbox '/inbox', :state =>'inbox'
    tasks.actions '/actions', :state =>'actions'
    tasks.waiting '/waiting', :state =>'waiting'
    tasks.someday '/someday', :state =>'someday'
    tasks.ticklers '/ticklers', :state =>'ticklers'
    tasks.reference '/reference', :state =>'reference'
  end

and you still get the named routes.

Or, junk having separate named routes and just do:

map.task_list '/:state', :controller => 'tasks', :action =>'task_list',
   :requirements => { :state => /\A(inbox|actions|waiting|someday|ticklers>reference)\z/ }

and use it in a view like:
   task_list_path(:state => 'inbox')

and in your controller:
   params[:state]

-Rob

Can you please explain to me what /\A(.....)\z/ does?

Thanks,

Alan

Can you please explain to me what /\A(.....)\z/ does?

Thanks,

Alan

It's a regular expression. \A matches the beginning of the string and
\z matches the end of the string. You might be more accustomed to
seeing ^ and $, but these match beginning and end of *line* and might
be confused by the presence of newlines in the string (granted that
such characters are unlikely in a URL component).

The use of the requirements is to keep "/nothing" from calling your
task_list with a params[:state]=='nothing'.

-Rob

Thanks!!

I tried this, but I got the following error:
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/routing.rb:954:in
`assign_route_options': Regexp anchor characters are not allowed in
routing requirements:
/\A(inbox|actions|waiting|someday|ticklers|reference)\z/
(ArgumentError)

When I remove the \A and \z, then it works just fine. If I pass it
/nothing, then I get a routing error. (as I would expect.)

--Alan

Hm, OK the code wins. I suppose it is possible for the anchors to be implicit in the route matching code (I've never looked into it). If a route like /spinboxes doesn't match the state 'inbox' (sp·inbox·es), then you'll be fine -- that's all that I was trying to help you avoid.
-Rob

Thanks for your help!! I checked and spinboxes doesn't match inbox....

-Alan