Skip to content

Instantly share code, notes, and snippets.

@lawso017
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lawso017/1095d2e8ba868fdd8a6c to your computer and use it in GitHub Desktop.
Save lawso017/1095d2e8ba868fdd8a6c to your computer and use it in GitHub Desktop.
Setting invalid JSON terminally breaks ActiveRecord object [Rails 4.2/PG using json datatype]
unless File.exist?('Gemfile')
File.write('Gemfile', <<-GEMFILE)
source 'https://rubygems.org'
gem 'rails', github: 'rails/rails'
gem 'arel', github: 'rails/arel'
gem 'pg'
GEMFILE
system 'bundle'
end
require 'bundler'
Bundler.setup(:default)
require 'active_record'
require 'minitest/autorun'
require 'logger'
# Note that testing jsonb datatype in pg requires Postgres 9.4. This behavior exists with json as well as jsonb datatypes.
ActiveRecord::Base.establish_connection(adapter: 'postgresql', host: 'localhost', username: 'postgres', password: 'yourpwd', database: 'yourdb')
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
t.json :content
end
end
class Post < ActiveRecord::Base
end
class BugTest < ActiveSupport::TestCase
def test_setting_invalid_json_terminally_breaks_activerecord_object
post = Post.create!
post.content = {title: 'This is a Hash'}
assert_nothing_raised{post.save!}
# Attempting to set content to invalid JSON raises an error
assert_raises(JSON::ParserError) {post.content = 'foo'}
# But after this error is raised, the object is terminally broken as we cannot reset the attribute
post.content = {title: 'This is a Hash'}
# I can buy that the invalid assignment would result in an error, but terminally breaking the object seems undesirable.
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment