I'm trying to implement a counter filter in my json. When I access the url api/v1/contacts?Results=2
[sic], I would like to get only two results from my json.
For this, I created two methods in my controller: an index that takes the information from the database and turns render into json, and a method that returns the number of times the json is returned.
class Api::V1::ContactsController < ApplicationController
before_action :results, only: [:index]
def index
@contacts = Contact.all
render json: {results: @contacts[0..@number_results]}
end
def results
if params[:results]
results = params[:results]["results"]
@number_results = results.to_i
else
@number_results = 3
end
end
end
Regardless of the value entered for results =
, the value of @number_results
is set to 0
, so whenever I type results = I
, get only the first result of json. If I do not type results =
in the url, it sets @number_results
to 3
, and shows four results on the screen.
Can anyone help?
First, in the url you propose, "Results" is capitalized. If that is how you intend to submit it, then you'll need to search for it that way on the back end. But since all your code uses lowercase "results", we'll go with that. You should modify your url in the same way: api/v1/contacts?results=2
.
If that's what your url looks like then the number you pass in is accessible in params[:results]
. If you pass no parameter, then params[:results]
will return nil
. Don't call #to_i
on the param before you check for its existence, because nil.to_i
is 0
.
All that said, here's what you probably want:
class Api::V1::ContactsController < ApplicationController
def index
number_results = params[:results] || 3
@contacts = Contact.all.limit(number_results.to_i)
render json: {results: @contacts}
end
end
If the result of params[:results]
is nil
, then number_results
is assigned 3
.
Now we use #limit
to return only the number of contacts that was requested. This allows us to do away with the #results
method entirely. You can also get rid of the before_action
callback.