How to get an array of objects after several ajax calls - ruby-on-rails

In a project, I implement checkbox filters via ajax. In my controller I have an action:
def casinos_filters
providers_from_categories = Provider.joins(:categories).where('categories.id = ?', params[:category_id])
providers = Casino.joins(:providers).where('providers.id = ?', params[:provider_id])
providers_from_categories.each do |provider|
#filtered_casinos = provider.casinos
end
casinos_list = []
casinos_list << #filtered_casinos if params[:category_id]
casinos_list << providers if params[:provider_id]
render json: { casinos: casinos_list.uniq }, status: 200
end
As a result, I want the array casinos_list include the casinos' objects. Clicking on a category checkbox, I get the json. But when I click the next category checkbox, the json doesn't have previous results. I think it's due to the initializing an empty array in the action. Is there any way to initialize the array only once, not on every ajax call? Thanks.

HTTP requests are stateless. You either need to store them in client side (as Javascript models/collections) or on the server side to be able to collect them together.

Related

Rails API get params to a custom method

Am trying to filter some data from database but its not getting params. This is my method:
def user_orders
orders = Order.select { | item | item[:user_id] == params[:id] }
if orders
render json: orders, status: :ok
else
render json: {error: "No orders available"}
end
end
This is the custom routing
get "/orders/user/:id", to: "orders#user_orders"
and the response is an empty array. However if I pass in a number in the method like so:
orders = Order.select { | item | item[:user_id] == 27 }
I get back the filtered array as expected. How can I pass in a dynamic ID from the routing?
EDIT: if your parameters look like this:
Parameters: { … "order"=>{…"user_id"=>27}}
… then you need to access the user_id as params[:order][:user_id].
Otherwise your conditional is comparing nil to 27, which will return false, and so nothing is ever selected.
If you’re querying an activerecord model, I also recommend that you use Order.where(item: {user_id: params[:id]}) to find your list of orders, so that and rails can cast to the right type as well.
What does the line in the rails log say? It should start with GET /user/orders and it should list what parameters have actually been received. Alternatively you can use puts to check the content of params.

Problem with selecting elements with the same params

What i do wrong? I want to return every products which pass condition:
def show
products = Product.select{|x| x[:category_id] == params[:id]}
render json: products
end
When i write
def show
products = Product.select{|x| x[:category_id] == 1}
render json: products
end
it works why the first example doesn't work?
I am pretty sure that there is mismatch in data type.
1=='1' #will be always false
1==1 #will be true
'1'=='1' #will be true as well
And also check for nil value from params[:id]
Please make sure to change as follows
def show
products = Product.select{|x| x.category_id == params[:id].to_i}
render json: products
end
OR
The best solution as suggested by #Eyeslandic is to use .where as it will not check for mismatch in data type. And also you don't have to take care of nil value from params[:id].
You should really be using a where to stop sql from loading all your products.
#products = Product.where('category_is = ?', params[:id])
The being said, if you are sticking to rails restful conventions, the fact you have a param called :id that is the category_id suggests you are on the category controller. So maybe consider changing your logic to:
#category = Category.includes(:products).find(params[:id])
you can then access products via
#category.products
or if your not interested in the category too much maybe
#products = Category.includes(:products).find(params[:id])&.products

Rails ActiveModelSerializer, combine two lists of same-type-models into one serialized response, with different names

I have a rails api, in which I'm using Active Model Serializers (version 0.10.6) to serializer json responses.
I have two arrays, both are of type "FeatureRequest" in an endpoint that returns a list of requests a user has made, and a second list of requests that a user is tagged in. Ideally, I'd like to serialize the response to look something like this:
{
"my_requests" : {
...each serialized request...
},
"tagged_requests" : {
...each serialized request, using the same serializer"
}
}
Is there some way to do this?
Here's my relevant controller method:
def index_for_user
user = User.includes(leagues: :feature_requests).find(params[:user_id])
# Find all requests that this user created
#users_created_feature_requests = FeatureRequest.requests_for_user(user.id)
#feature_requests_in_tagged_leagues = []
user.leagues.each do |league|
#feature_requests_in_tagged_leagues << league.feature_requests
end
...some serialized response here
end
In this code, the two lists are #users_created_feature_requests, and #feature_requests_in_tagged_leagues
Thanks!
Assuming you have a serializer like FeatureRequestSerializer, you can achieve that in the following way:
def index_for_user
user = ...
users_created_feature_requests = ...
feature_requests_in_tagged_leagues = user.leagues.map(&:feature_requests)
# serialized response
render json: {
my_requests: serialized_resource(users_created_feature_requests)
tagged_requests: serialized_resource(feature_requests_in_tagged_leagues)
}
end
private
def serialized_resource(collection, adapter = :attributes)
ActiveModelSerializers::SerializableResource.new(collection,
each_serializer: FeatureRequestSerializer,
adapter: adapter
).as_json
end

Autocomplete action parses a large JSON file at each ajax call (make it faster)

I am trying to make an autocomplete model for cities and zipcode using Rails 4 and Jquery ui.
I have a large JSON file (about 500,000 lines) that contains an array (cp_autocomplete) that contains zipcode (CP) and cities (CITY).
In my current model, on every ajax query the autocomplete action reads the JSON file, parses it and then search for a zipcode or city, makes a list of nine zipcode+cities (if found) and render the list as json.
This works but it makes more than 2 seconds to render a list.
Any ideas to make it runs faster?
- How could I parse the json file once and not on every ajax query?
- I thought of caching the parsed json value and then delete it after 1 minute for example.
Here is my autocomplete action:
def autocomplete
require 'auto_compeletion_cp_city' #a class that has PostalCode and City attributes
postal_file = File.read("#{Rails.root}/public/postal_code_fr.json")
postal_parse = JSON.parse(postal_file)
#list = []
if !(ActionController::Base.helpers.sanitize(params[:Postalcode]).blank?)
search_term = ActionController::Base.helpers.sanitize(params[:Postalcode])
search = /\A#{search_term}/
postal_parse["cp_autocomplete"].each do |f|
if search.match("#{f['CP']}",0) && (#list.length < 9)
selected = AutoCompletionCpCity.new
selected.PostalCode = f['CP']
selected.City = f['CITY']
#list << selected
end
end
else
if !(ActionController::Base.helpers.sanitize(params[:city]).blank?)
search_term = ActionController::Base.helpers.sanitize(params[:city])
search = /\A#{Regexp.escape(search_term)}/i
postal_parse["cp_autocomplete"].each do |f|
if search.match("#{f['CITY']}",0) && (#list.length < 9)
selected = AutoCompletionCpCity.new
selected.PostalCode = f['CP']
selected.City = f['CITY']
#list << selected
end
end
end
end
respond_to do |format|
format.json {
render json: #list
}
end
end
Create a small module to house the postal code data. It can parse the file once when the process starts and hold onto it forever. Since postal codes don't change often (and this file is in your repo, so changing it requires a deploy), there's no reason to cache for just 1 minute.
module PostalCodes
DATA = JSON.parse(File.read("#{Rails.root}/public/postal_code_fr.json"))
end
This module can also be responsible for searching the codes and other behavior you need.
Before you get too deep in this, as with all performance optimization, you should verify the part of your code that's causing search to take 2 seconds. If it's the JSON parsing, caching the data will help, but if it's running a regular expression over ever postal code, you need a different solution.

instance variable is null in show method rails

I have developed a rest api, in which I am using instance variable. there are two methods index and show, I have created a instance variable in index method which I want to use in show method on user request.
But i do not know, the instance variable is null in show method, I am sure that I am not initaializing the class anywhere explicitly. Code snippet is below
def index
data = Hash.new
#temp = DataHelper.filter(params)
if(params[:type] == 'Student')
json = DataStudenteHelper.sfilter(params, #temp)
else
json = EmpDataHelper.empfilter(params, #temp)
end
puts data.to_json
render :status => :ok, :json => json
end
def show
puts #temp.to_json // null here
if (params[:type] == 'Student')
#h = StudentHelpHelper.shfilter(params, #temp)
else
#h = EmpDataHelpHelper.emphfilter(params, #temp)
end
render :status => :ok, :json => #h
end
in the methods sfilter, empfilter, shfilter and emphfilter, I am just processing #temp but it is null in show method...
So any idea what is the issue thanks...
You seem to be assuming that a controller will persist across multiple requests so that you can initialize a variable in an index action and still be able to use it in a subsequent show action. This is not the case. Rails controller instances exist only for the duration of the request they serve. You cannot keep values in memory like this across requests (nor should you want to as that would require that requests be served in a particular order and would leak data between different users).
If you need to initialize this variable before all of your controller actions consider using a before filter. In your case this probably means that you also need to supply the data you need in the params of the show action.

Resources