views:

35

answers:

2

Hello,

I am a beginner when it comes to Ruby on Rails, so I need a little bit of help. I started reading a basic tutorial recently, which was taught using Scaffolding. I made a "Clients" model: script/generate scaffold clients name:string ip_address:string speed:integer ... Inside the clients_controller.rb file, there is a method called show:

  # GET /clients/1
  # GET /clients/1.xml
  def show
    @client = Client.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @client }
    end
  end

For queries, I'd go to localhost:3000/clients/{Enter the ID here}. Instead of searching with the ID are the argument, I'd like to search with another value, like ip_address or speed, so I thought all I would have to do is change :id to :ip_address in "@client = Client.find(params[:id])". However, that does not work, so would someone please tell me how I can achieve a search with another parameter. Thanks!

+1  A: 

This doesn't work because of the way things are routed

When you do something like

map.resources :client (See config/routes.rb)

This happens automatically when you use scaffold. It sets up routes based on the assumption you're using an id.

One of these routes is something like

map.connect 'clients/:id', :controller => 'client', :action => 'show'

So :id is passed as a parameter as part of the URL.

You shouldn't have the IP be the primary identifier unless they're distinct - and even then it kind of messes with the RESTful routing.


If you want to have the ability to search by IP, modify your index action for the clients

def index
  if params[:ip].present?
    @clients = Client.find_by_ip_address(params[:ip]);
  else
    @clients = Client.all
  end
end

Then you can search by ip by going to clients?ip=###.###.###

Jamie Wong
A: 

This line in your routes.rb file

map.connect 'clients/:id', :controller => 'client', :action => 'show'

implies that when the dispatcher receives an URI in the format "clients/abcdxyz' with GET Method, it will redirect it to show method with the value "abcdxyz" available in params hash with key :id.

EDIT


Since you have used scaffold, the clients resource will be RESTful. That means that when you send a GET request to "/clients/:id' URI, you will be redirected to show page of that particular client.


In your controller code you can access it as

params[:id] # which will be "abcdxyz"

The find method that is generated by scaffold searches on the primary key i.e 'id' column. You need to change that statement to either

@client = Client.find_by_ip_address(params[:id]) #find_by_column_name

OR

@client = Client.find(:first, :conditions => [":ip_address = ?", params[:id]])

:-)

Jagira
He scaffolded, which I'm pretty sure creates a `map.resources` line, not a `map.connect`
Jamie Wong
oops.... yeah.... thanks for pointing that out
Jagira