ruby-on-railsrestgetgrape-apiruby-on-rails-5.1

Limit parameter in get request not working in Rails 5 Grape Api


I built my first api and it works as expected, but I am having a hard time understanding why I can't limit the results in my request. All the searches I've seen on the subject list the limit param the same as I have it listed below. My api is built with Grape inside Rails 5. Any ideas what I am doing wrong?

https://www.soledadmemorial.com/api/v1/plaques?limit=10

controllers/api/v1/plaques.rb

module API  
    module V1
      class Plaques < Grape::API
        include API::V1::Defaults

        resource :plaques do
          desc 'Return all Plaques'
          get '', root: :plaques do
             Plaque.all
          end

          desc 'Return a Plaque'
          params do
            requires :id, type: String, desc: 'ID of Plaque'
          end
          get ':id', root: 'plaque' do
            Plaque.where(id: permitted_params[:id]).first!
          end
        end
      end
    end
  end 

plaques_controller.rb

class PlaquesController < ApplicationController
  before_action :authenticate_user!, :except => [:index, :show]
  before_action :set_plaque, only: [:show, :edit, :update, :destroy]

  # GET /plaques
  # GET /plaques.json
  def index
    @plaquelist = Plaque.search(params[:search]).paginate(:per_page => 10, :page => params[:page])
    @plaques = Plaque.all
  end

  # GET /plaques/1
  # GET /plaques/1.json
  def show
    @plaques = Plaque.all
  end

  # GET /plaques/new
  def new
    @plaque = Plaque.new
  end

  # GET /plaques/1/edit
  def edit
  end

  # POST /plaques
  # POST /plaques.json
  def create
    @plaque = Plaque.new(plaque_params)

    respond_to do |format|
      if @plaque.save
        format.html { redirect_to @plaque, notice: 'Plaque was successfully created.' }
        format.json { render :show, status: :created, location: @plaque }
      else
        format.html { render :new }
        format.json { render json: @plaque.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /plaques/1
  # PATCH/PUT /plaques/1.json
  def update
    respond_to do |format|
      if @plaque.update(plaque_params)
        format.html { redirect_to @plaque, notice: 'Plaque was successfully updated.' }
        format.json { render :show, status: :ok, location: @plaque }
      else
        format.html { render :edit }
        format.json { render json: @plaque.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /plaques/1
  # DELETE /plaques/1.json
  def destroy
    @plaque.destroy
    respond_to do |format|
      format.html { redirect_to plaques_url, notice: 'Plaque was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
  # Use callbacks to share common setup or constraints between actions.
  def set_plaque
    @plaque = Plaque.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def plaque_params
    params.require(:plaque).permit(
        :veteran_war,
        :veteran_biography,
        :veteran_first,
        :veteran_last,
        :veteran_display_name,
        :group_type,
        :veteran_nickname,
        :group_name,
        :veteran_middle,
        :veteran_rank,
        :veteran_branch,
        :grid, :wall,
        :direction,
        :row,
        :plaque_num,
        :image,
        :search
    )
  end
end

Solution

  • I'm not 100% sure which action it's going through - but to assume index for now:

    def index
      @plaquelist = Plaque.search(params[:search]).paginate(:per_page => 10, :page => params[:page])
      @plaques = Plaque.all
      return unless params[:limit]
      @plaquelist = @plaquelist.limit(params[:limit])
      @plaques = @plaques.limit(params[:limit])
    end
    

    I've not tested that but in theory if there is a limit param (which there is on the URL you gave) then it will take that limit and apply it to the objects you're returning. At the moment your controller isn't doing any logic with the limit parameter even if it's present.

    This logic will 'return' after your code if there is no limit paramater, and if there is will change the results being given from the controller.

    EDIT: can also be tidied up a bit but will leave the fun parts to you :D