简体   繁体   中英

Rails way to define parameter for filter

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM