Reputation: 12179
There is the following routes:
namespace :api do
namespace :v1 do
resources :places, only: [:index]
end
end
The code of the controller:
class API::V1::PlacesController < API::V1::ApplicationController
def index
@places = (!params[:id]) ? Place.all : Place.find_all_by_type_id(params[:id])
respond_to do |format|
format.json { render json: @places }
format.html
end
end
end
'Place' has 'type_id' field, and I want to filter places by its filter_id. As you can see, now I send the parameter through URL as "places?id=1". But may be I must send parameter as "places/1"? I need also to set up paths; now they doesn't work with "?id=1" form. Please, tell me, how should I do? Thanks.
Upvotes: 0
Views: 99
Reputation: 1793
My recommendation is to rewrite it like this:
# Your routes
namespace :api do
namespace :v1 do
resources :places, only: [:index]
get "/places/by_type/:type_id" => "places#by_type", as: :places_by_type
end
end
# Your controller
class API::V1::PlacesController < API::V1::ApplicationController
def index
respond_to do |format|
format.json { render json: @places }
format.html
end
end
def by_type
@places = Place.where(type_id: params[:type_id])
respond_to do |format|
format.js { render json: @places }
format.html do
render action: "index"
end
end
end
end
I could be slightly wrong about the routes, but I'm pretty sure it should work.
Upvotes: 0
Reputation: 3459
Rails convention would be to have the list of the places in the "index" action mapped to the relative path /places
(GET method).
And then /places/1
(GET) would be mapped to "show", which is intended for presenting a member of the collection. For "show", the route would assign the ID segment of the path ("1") to params[:id]
.
The guides have a table of default route mappings. The :type_id
attribute in the model vs. the :id
attribute in the route probably confused you.
A simple solution would be to use /places?type_id=1
instead. In your controller, you can have something like:
def index
collection = Place.all
collection = collection.where(:type_id => params[:type_id].to_s) unless params[:type_id].to_s.blank?
respond_to do |format|
# ...
end
end
Setting :type_id
as a query parameter instead of integrating into the relative path seems especially reasonable to me since you are building an API and might add support for more filters in the future.
Upvotes: 1