iosruby-on-railsparametersafnetworking

iOS get request to Rails API with Parameters


In my rails app:

When the iOS app calls locations/%@/beers.json I want the Beers Controller to respond with beers that belong only to the location_id that is being called from my iOS app.

Here is the request sent from the client when a user taps on location 1.

Started GET "/locations/1/beers.json" for 127.0.0.1 at 2013-03-09 11:26:16 -0700
Processing by BeersController#index as JSON
  Parameters: {"location_id"=>"1"}
  Beer Load (0.1ms)  SELECT "beers".* FROM "beers" 
Completed 200 OK in 12ms (Views: 1.8ms | ActiveRecord: 0.4ms)

Here is my Beer Controller code:

class BeersController < ApplicationController

  def index
    @beers = Beer.all
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @beers }
    end
  end

Right now, this returns a list of all beers to the client regardless of their location_id.

So far I've tried:

class BeersController < ApplicationController

  def index
    @beers = Beer.find(params[:location_id])
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @beers }
    end
  end

But that crashes the iOS app even though I get a status 200:

 Started GET "/locations/1/beers.json" for 127.0.0.1 at 2013-03-09 11:19:35 -0700
    Processing by BeersController#index as JSON
      Parameters: {"location_id"=>"1"}
      Beer Load (0.1ms)  SELECT "beers".* FROM "beers" WHERE "beers"."id" = ? LIMIT 1  [["id", "1"]]
    Completed 200 OK in 2ms (Views: 0.6ms | ActiveRecord: 0.1ms)

In the above request shouldn't it be:

Beer Load (0.1ms) SELECT "beers".* FROM "beers" WHERE "beers"."location_id" = ? LIMIT 1 [["location_id", "1"]]

How can I change my controller so that it responds with beers that belong only to the location_id that is being sent by the client?


Solution

  • First of all, the action you're looking for is show, not index if you're looking for a RESTful service.

    To fix the error you mention you need to change your query to:

    @beers = Beer.where(:location_id => params[:location_id])
    

    Assuming location_id is the field you're looking for.

    I would look hard at your routes, which define your urls. They don't follow normal conventions.

    /locations/... would belong to a Location resource.

    /beers/... would belong to a Beer resource.

    You're messing with convention (which works against you) with your current routes.