I have a Ruby on Rails 5.2.4 running on Ruby 2.6.6. The frontend expects that the data returned by the backend is a JSON structured on: "resources" (if there is a list of data) or "recource" if there is only one data.
The app was created for Rails 5.0 and I made some updates so it will work well on Rails 5.2 also. Maybe I missed something.
The routes.rb looks like:
resources :route_a, only: [:index, :show]
resources :route_b, only: [:index]
resources :route_c, only: [:create]
resource :route_d, only: [:create, :update, :destroy]
...
resources :route_e, only: [] do
resource :route_f, only: [] do
post 'route_g', on: :member
end
end
The frontend Javascript framework expects the returned data to contain a "resources" or "resource" key. But in 80% of cases the data doesn't return the resources/resource structured JSON. What is wrong with Rails? Is this issue related to a gem, to the database? Why for some routes the response is returned in a resources/resource structured data and for other routes the plain JSON is returned?
Instad of a response such as:
[{"id":33,"type":"M..
I need to have:
[{"resources":{"id":33,"type":"M...
I'm new to Rails, sorry for probably asking basic things, but I don't know what's the issue here. Thank you.
Important
I have a file: config/initializers/wrap_parameters.rb
that contains:
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
# self.include_root_in_json = true
# end
Important 2
This is the /api/integrations
page controller:
class IntegrationsController < ApiController
def index
integrations = policy_scope(Integration)
integrations = integrations.where(type: params[:type_eq]) if params[:type_eq]
render_resources integrations, ransack_query: params[:q]
end
end
The api/integrations
response is:
[{"id":254,"name":"Integration 1"...
The result doesn't contain any resources
key inside. I described the render_resources
method below:
def render_resources(resources, options = {})
options[:pagination] = true if options[:pagination].nil?
pagination = options.delete(:pagination)
ransack_query = options.delete(:ransack_query) || {}
ransack_sort = options.delete(:ransack_sort) || params[:sort]
resources = resources.ransack(ransack_query.to_hash.merge(s: ransack_sort)).result if ransack_sort || ransack_query.any?
total = resources.respond_to?(:total_count) ? resources.total_count : resources.length
default = {root: :resources, meta: {total: total}}
results = pagination ? resources.page(params[:page]).per(params[:per_page]) : resources
results = results.includes(options[:includes]) if options[:includes]
render({json: results}.merge(default).merge(options))
end
Since this method doesn't return anymore the response containing a resources
key, am I right to say that it's because of the implied libraries - Ransack and Pagination? Because up until I updated ruby and rails gems, the functionality worked as expected. Still, I don't know what is the library that should structure the response's JSON data in a resources
or resource
key.
If you went straight from rails 5.0 to 5.2 you might have skipped fixing some deprecation warnings present in 5.1. Same situation with ruby upgrades - unless you have vast test coverage and everything works fine - it's better to go one minor (5.0->5.1->5.2) version at a time.
Also during rails upgrade other gems are also upgraded, each new version of each gem might have some breaking changes (or new bugs)
If you're using active_model_serializers - you might have effects from their changes to default adapter (now it's json_api
) and other movement around root
option, see changelog for 0.10 and previous changelogs depending on version you're upgrading from