如何在RubyonRails API中以特定方式对相关资源进行排序

如何在RubyonRails API中以特定方式对相关资源进行排序,api,ruby-on-rails-4,Api,Ruby On Rails 4,我必须建模类:TBM和位置 TBMs是父表,位置是子表。 我有一个完全开发的RoR应用程序,我想为它开发一个API。 我开始为TBM开发API/V1控制器 class Api::V1::TbmsController < Api::V1::BaseController before_filter :authenticate_user! before_action :set_tbm, only: [:show, :update] def index tbms = Tbm.

我必须建模类:TBM和位置 TBMs是父表,位置是子表。 我有一个完全开发的RoR应用程序,我想为它开发一个API。 我开始为TBM开发API/V1控制器

class Api::V1::TbmsController < Api::V1::BaseController
  before_filter :authenticate_user!
  before_action :set_tbm, only: [:show, :update]

  def index
    tbms = Tbm.order(:id)
    render json: tbms
  end 

  private
    def set_tbm
      @tbm = Tbm.find(params[:id])
    end

    def tbm_params
      params.require(:tbm).permit(:tbm_name, :chainage_direction).delete_if{ |k,v| v.nil? }
    end
end
curl命令是:

curl -i -X GET \
   -H "Authorization:Token token=\"mytoken\", email=\"myemail@gmail.com\"" \
   -H "Content-Type:application/json" \
 'http://localhost:3000/api/v1/tbms/'
返回的JSON是:

{
"tbms":[
{
"id": 1,
"tbm_name": "Denis",
"chainage_direction": "Ascending",
"created_at": "2014-11-13T19:00:00-05:00",
"updated_at": "2015-11-16T17:36:10-05:00"
},
{
"id": 2,
"tbm_name": "Lea",
"chainage_direction": "Ascending",
"created_at": "2014-11-13T19:00:00-05:00",
"updated_at": "2015-11-04T15:27:54-05:00"
}
]
}

我正在用Restlet的Chrome扩展DHC测试我的API。

解决方案依赖于位置控制器和嵌套路由:

  #api
  namespace :api do
    namespace :v1 do
      resources :users,     only: [:index, :create, :show, :update, :destroy]
      resources :sessions,  only: [:create]
      resources :tbms,      only: [:index, :edit, :update, :show] do
        resources :locations, only: [:index, :show]
      end
      resources :locations, only: [:index, :create, :show, :update, :destroy]
    end
  end
以及更改位置控制器以接受索引方法的参数:

class Api::V1::LocationsController < Api::V1::BaseController
  before_filter :authenticate_user!
  before_action :set_location, only: [:show, :update, :destroy]

  def index
    if params[:tbm_id]
      locations = Location.where("tbm_id = '#{params[:tbm_id]}'").order("daily_date DESC")
    else
      locations = Location.order("daily_date DESC, tbm_id")
    end
    #locations = apply_filters(locations, params)
    render json: locations
  end

  def show
    render json: @location
  end

  def update
    if @location.update(location_params)
      render json: @location, status: 200, location: api_v1_location_path(@location.id)
    else
      return api_error(status: 422, errors: @location.errors)
    end
  end

  def create
    location = Location.new(location_params)
    if location.save!
      render json: location, status: 201, location: api_v1_location_path(location.id)
    else
      return api_error(status: 422, errors: location.errors)
    end
  end

  def destroy
    if @location.destroy
        head status: 204
    else
      return api_error(status: 422, errors: @location.errors)
    end
  end

  private
    def set_location
      @location = Location.find(params[:id])
    end

    def location_params
      params.require(:location).permit(:tbm_id, :daily_date, :station, :tbm_status, :latitude, :longitude).delete_if{ |k,v| v.nil? }
    end
end

问题已解决。

您的问题是什么?我希望在检索两个TBM时,索引方法还包括子表位置中每个TBM的位置,并按每日日期降序排序(从最新日期开始枚举位置)。为了简单起见,这里是我的问题的重新表述:我想从按ID升序排序的父表中检索到两个TBM,在相同的JSON响应中,我想为每个TBM获取从按每日日期降序排序的子表(位置)中检索到的每日位置,即从今天的日期开始。
class Api::V1::LocationsController < Api::V1::BaseController
  before_filter :authenticate_user!
  before_action :set_location, only: [:show, :update, :destroy]

  def index
    if params[:tbm_id]
      locations = Location.where("tbm_id = '#{params[:tbm_id]}'").order("daily_date DESC")
    else
      locations = Location.order("daily_date DESC, tbm_id")
    end
    #locations = apply_filters(locations, params)
    render json: locations
  end

  def show
    render json: @location
  end

  def update
    if @location.update(location_params)
      render json: @location, status: 200, location: api_v1_location_path(@location.id)
    else
      return api_error(status: 422, errors: @location.errors)
    end
  end

  def create
    location = Location.new(location_params)
    if location.save!
      render json: location, status: 201, location: api_v1_location_path(location.id)
    else
      return api_error(status: 422, errors: location.errors)
    end
  end

  def destroy
    if @location.destroy
        head status: 204
    else
      return api_error(status: 422, errors: @location.errors)
    end
  end

  private
    def set_location
      @location = Location.find(params[:id])
    end

    def location_params
      params.require(:location).permit(:tbm_id, :daily_date, :station, :tbm_status, :latitude, :longitude).delete_if{ |k,v| v.nil? }
    end
end
curl -i -X GET \
   -H "Authorization:Token token=\"mytoken\", email=\"myemail@gmail.com\"" \
   -H "Content-Type:application/json" \
 'http://localhost:3000/api/v1/tbms/1/locations/'