Reason is that in active_support it tries to call ::JSON.parse with two parameters — the JSON payload and options. Meanwhile a couple days back that method signature changed so that those options come in as the “keyrest” part of the parameters (i.e. the rest of any keyword parameters aside from the ones specifically called out, which are on_load, object_class, and array_class).
Try putting this into your Gemfile, then bundle, and see if everything is happy:
This doesn’t help.
I put
gem 'json', '< 3.0.2'
at the bottom of Gemfile. Ran bundle install. The same thing. An error on the page http://localhost:3000/products and working localhost:3000 while removing root “products#index”.
I just created the app with ‘rails new App -d postgresql’, and when I added the first route ‘get ’/products’, to: ‘products#index’, it started failing—every time I make a change, I get a 500 error. After every change, I have to open an incognito window to check it, and when I make another change, I get a 500 error again. I have to close that window, open a new one, and then I can check the new change. I’ve already installed JSON 3.0.2, and it’s still the same.
Some additional info. I’ve noticed that a 500 error appears only when rails sets up a session cookie in the browser. After I manually cleared the session cookie, the page loads ok, but after the browser refresh I’ve got a 500 error.
To reproduce
$ rails new blog
$ cd blog
$ ./bin/rails g scaffold post title content
$ ./bin/rails db:migrate
I figured it out—as Lorin said, it’s a compatibility issue with version 3.x.x of JSON. Just change it in the Gemfile to (gem ‘json’, ‘< 2.10’) and run bundle update json.
p.s. - for anyone wanting to use the newer JSON gem then here’s a monkey patch to smarten up the newer JSON#parse method so that it will work with both Rails < 8.2 and edge Rails:
# Monkey patch to allow Rails < 8.2 to work with json gem >= 3.0
require 'json'
if ::JSON.method(:parse).parameters.select { |p| [ :req, :opt ].include?(p.first) }.length < 2
::JSON.module_exec do
# This "define_singleton_method" trick is the same general idea as aliasing in this way:
# alias_method :_orig_parse, :parse
# but works in a module instead of a class.
define_singleton_method(:_orig_parse, singleton_method(:parse))
module_function
def parse(source, options_param = nil, **options)
options.merge!(options_param) if options_param
_orig_parse(source, **options)
end
end
end
If you put this at the end of your boot.rb file then it will allow JSON v3.02 to work.
It looks like the issue may be with how the root route was added. In Rails, it should be written inside config/routes.rb like this:
Rails.application.routes.draw do
root "products#index"
end
Also, make sure the ProductsController has an index action and that the corresponding view exists. If you’re still getting the error, please share the exact error message and your config/routes.rb file so others can identify the issue.