json_record
json_record copied to clipboard
Not compatible with Rails 4.2 beta2
Here is a proof of the bug: https://github.com/MichaelSp/json_record_bug
You can switch in the Gemfile between the working and the non working version and than run:
rm Gemfile.lock && bundle install && rake test
This is the error
1) Error:
PostTest#test_create_posts:
ActiveRecord::StatementInvalid: SQLite3::SQLException: table posts has no column named email: INSERT INTO "posts" ("author", "body", "created_at", "email", "first_name", "last_name", "title", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?)
sqlite3 (1.3.9) lib/sqlite3/database.rb:91:in `initialize'
sqlite3 (1.3.9) lib/sqlite3/database.rb:91:in `new'
sqlite3 (1.3.9) lib/sqlite3/database.rb:91:in `prepare'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/sqlite3_adapter.rb:312:in `block in exec_query'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract_adapter.rb:464:in `block in log'
activesupport (4.2.0.beta2) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract_adapter.rb:458:in `log'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/sqlite3_adapter.rb:299:in `exec_query'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract/database_statements.rb:76:in `exec_insert'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract/database_statements.rb:108:in `insert'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
activerecord (4.2.0.beta2) lib/active_record/relation.rb:66:in `insert'
activerecord (4.2.0.beta2) lib/active_record/persistence.rb:521:in `_create_record'
activerecord (4.2.0.beta2) lib/active_record/counter_cache.rb:139:in `_create_record'
activerecord (4.2.0.beta2) lib/active_record/attribute_methods/dirty.rb:122:in `_create_record'
activerecord (4.2.0.beta2) lib/active_record/callbacks.rb:306:in `block in _create_record'
activesupport (4.2.0.beta2) lib/active_support/callbacks.rb:83:in `run_callbacks'
activerecord (4.2.0.beta2) lib/active_record/callbacks.rb:306:in `_create_record'
activerecord (4.2.0.beta2) lib/active_record/timestamp.rb:57:in `_create_record'
activerecord (4.2.0.beta2) lib/active_record/persistence.rb:501:in `create_or_update'
activerecord (4.2.0.beta2) lib/active_record/callbacks.rb:302:in `block in create_or_update'
activesupport (4.2.0.beta2) lib/active_support/callbacks.rb:114:in `call'
activesupport (4.2.0.beta2) lib/active_support/callbacks.rb:114:in `call'
activesupport (4.2.0.beta2) lib/active_support/callbacks.rb:166:in `block in halting'
activesupport (4.2.0.beta2) lib/active_support/callbacks.rb:87:in `call'
activesupport (4.2.0.beta2) lib/active_support/callbacks.rb:87:in `run_callbacks'
activerecord (4.2.0.beta2) lib/active_record/callbacks.rb:302:in `create_or_update'
activerecord (4.2.0.beta2) lib/active_record/persistence.rb:120:in `save'
activerecord (4.2.0.beta2) lib/active_record/validations.rb:36:in `save'
activerecord (4.2.0.beta2) lib/active_record/attribute_methods/dirty.rb:21:in `save'
activerecord (4.2.0.beta2) lib/active_record/transactions.rb:284:in `block (2 levels) in save'
activerecord (4.2.0.beta2) lib/active_record/transactions.rb:345:in `block in with_transaction_returning_status'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract/transaction.rb:188:in `within_new_transaction'
activerecord (4.2.0.beta2) lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
activerecord (4.2.0.beta2) lib/active_record/transactions.rb:218:in `transaction'
activerecord (4.2.0.beta2) lib/active_record/transactions.rb:342:in `with_transaction_returning_status'
activerecord (4.2.0.beta2) lib/active_record/transactions.rb:284:in `block in save'
activerecord (4.2.0.beta2) lib/active_record/transactions.rb:299:in `rollback_active_record_state!'
activerecord (4.2.0.beta2) lib/active_record/transactions.rb:283:in `save'
activerecord (4.2.0.beta2) lib/active_record/persistence.rb:34:in `create'
test/models/post_test.rb:5:in `block in <class:PostTest>'
minitest (5.4.2) lib/minitest/test.rb:108:in `block (3 levels) in run'
minitest (5.4.2) lib/minitest/test.rb:206:in `capture_exceptions'
minitest (5.4.2) lib/minitest/test.rb:105:in `block (2 levels) in run'
minitest (5.4.2) lib/minitest/test.rb:258:in `time_it'
minitest (5.4.2) lib/minitest/test.rb:104:in `block in run'
minitest (5.4.2) lib/minitest.rb:319:in `on_signal'
minitest (5.4.2) lib/minitest/test.rb:278:in `with_info_handler'
minitest (5.4.2) lib/minitest/test.rb:103:in `run'
minitest (5.4.2) lib/minitest.rb:761:in `run_one_method'
minitest (5.4.2) lib/minitest.rb:293:in `run_one_method'
minitest (5.4.2) lib/minitest.rb:287:in `block (2 levels) in run'
minitest (5.4.2) lib/minitest.rb:286:in `each'
minitest (5.4.2) lib/minitest.rb:286:in `block in run'
minitest (5.4.2) lib/minitest.rb:319:in `on_signal'
minitest (5.4.2) lib/minitest.rb:306:in `with_info_handler'
minitest (5.4.2) lib/minitest.rb:285:in `run'
minitest (5.4.2) lib/minitest.rb:149:in `block in __run'
minitest (5.4.2) lib/minitest.rb:149:in `map'
minitest (5.4.2) lib/minitest.rb:149:in `__run'
minitest (5.4.2) lib/minitest.rb:126:in `run'
minitest (5.4.2) lib/minitest.rb:55:in `block in autorun'
8 runs, 13 assertions, 0 failures, 1 errors, 0 skips
I came up with an work around for that, called JsonStore:
put this into your app/models/concerns directory
module JsonStore
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def in_json(store: :json_data, attributes:)
attributes.each do |attr_name|
define_method "#{attr_name}=".to_sym do |value|
send(store)[attr_name] = value
value
end
define_method attr_name do
send(store)[attr_name]
end
define_method store do
ivar = instance_variable_get "@#{store}".to_sym
ivar ||= (JSON.parse(self[store]) rescue {}).with_indifferent_access
instance_variable_set "@#{store}".to_sym, ivar
ivar
end
class_eval <<-EOF
before_save do
self.#{store} = @#{store}.to_json
end
EOF
end
end
end
end
And use it like this:
class Company < ActiveRecord::Base
include JsonStore
in_json store: :contact_person, attributes: [:contact_name, :email, :phone]
validates :phone, format: { with: /\A[+]*[0-9\.\\ -]+\z/, message: 'Wrong phone number'}
validates :email, uniqueness: false, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, message: 'Illegal email address'}
validates_presence_of :contact_name, :email, :phone
validates_uniqueness_of :name
end