In my rails app:
Locations have_many Beers
Beers belong_to location
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?
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.