The challenge you’re facing arises because when data is passed from the client (e.g., via query parameters in an HTTP request), nil
and null
are converted to strings like "nil"
or "null"
instead of being interpreted as Ruby's nil
. Here's how you can properly handle this scenario in your Rails application:
Solution 1: Parameter Conversion in Controller
One way to solve this issue is by converting "nil"
or "null"
values back to nil
in the Rails controller. You could define a helper method to process the parameters.
Example
# app/controllers/products_controller.rb class ProductsController < ApplicationController def index category_id = convert_to_nil(params[:category_id]) @products = Product.search('*', where: { category_id: category_id }) render json: @products end private def convert_to_nil(value) value.in?(['nil', 'null', '']) ? nil : value end end
Solution 2: Use a Custom JavaScript Value
You can avoid sending "nil"
or "null"
from the frontend by sending an explicit placeholder value (e.g., "__nil__"
) to signal the need for nil
in the backend.
JavaScript Code
const query = { category_id: selectedCategory || "__nil__" }; fetch(`/products?${new URLSearchParams(query)}`);
Controller Adjustment
def index category_id = params[:category_id] == '__nil__' ? nil : params[:category_id] @products = Product.search('*', where: { category_id: category_id }) render json: @products end
Solution 3: Use presence
or blank?
Check
If the presence or absence of the parameter is enough to decide the query logic, you could use Rails’ presence
method:
category_id = params[:category_id].presence @products = Product.search('*', where: { category_id: category_id })
Solution 4: Encode nil
Using Query Parameter Standards (Optional)
If you are using JSON in the body of requests instead of query parameters, you can directly pass null
in the JSON payload.
fetch('/products', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ category_id: null }), });
Controller Example
def index category_id = params[:category_id] @products = Product.search('*', where: { category_id: category_id }) render json: @products end
These solutions help ensure that nil
is correctly interpreted without requiring excessive manipulation of the params
hash in every request.