Skip to content

Commit

Permalink
Add support for attribute default
Browse files Browse the repository at this point in the history
JSON attributes can now use a default. Documentation has been added for the proper way to do it.

Closes #4.
  • Loading branch information
64kramsystem committed Feb 14, 2018
1 parent 9fb58f6 commit d4066a0
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
7 changes: 5 additions & 2 deletions lib/active_record/type/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ def type_cast_for_database(value)
private

def cast_value(value)
if value.is_a?(::String)
case value
when ::String
JSON.parse(value)
when Hash, Array
value
else
raise "Unexpected JSON data type when loading from the database: #{value.class}"
raise "Unexpected JSON stored or default data type: #{value.class}"
end
end
end
Expand Down
44 changes: 44 additions & 0 deletions spec/json_on_rails/json_attributes_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,48 @@
end
end
end

# Smoke tests, to verify that the default works.
#
context "with Rails-defined defaults" do
# If a plain `{}` (or `[]`) is used as default, it will be shared on each model instantiation.
#
# This can be solved by using:
#
# attribute :extras, ActiveRecord::Type::Json.new, default: -> { {} }
#
# but the following support would be required:
#
# - Type::Json: procs in #cast_value;
# - Proc: (Rails) marshalling, in case a dev wants to serialize the instance.
#
# which is not really worth.
#
context "on instantiation" do
it "should set the default" do
user_with_default = WithDefaultUser.new

expect do
user_with_default.extras["amiga500"] = "awesome"
user_with_default.save!
end.not_to raise_error
end
end

context "on create!" do
it "should set the default" do
user = WithDefaultUser.create!

expect { user.extras["amiga500"] = "awesome" }.not_to raise_error
end

it "should save the value when saving, even when not setting it" do
WithDefaultUser.create!

user = WithDefaultUser.find_by("extras LIKE ?", {}.to_json)

expect(user).not_to be(nil)
end
end
end
end
6 changes: 5 additions & 1 deletion spec/setup/db/schema.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# frozen_string_literal: true

ActiveRecord::Schema.define(version: 20180210000000) do
ActiveRecord::Schema.define(version: 20180214000000) do
create_table "users" do |t|
t.json "extras"
end

create_table "with_default_users" do |t|
t.json "extras"
end
end
7 changes: 7 additions & 0 deletions spec/setup/models/with_default_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class WithDefaultUser < ActiveRecord::Base
after_initialize do |instance|
instance.extras = {}
end
end

0 comments on commit d4066a0

Please sign in to comment.