1

model

class PushNotificationRequest < ApplicationRecord
  serialize :details
migration
class CreateNotificationRequests < ActiveRecord::Migration[5.2]
  def change
    create_table :notification_requests do |t|
      t.references :order, references: :spree_orders, index: false
      t.string :key                             
      t.json :details                           
      t.string :type
      t.timestamps
    end
  end
end

Data creation on console

PushNotificationRequest.create(order: Spree::Order.last, details: {a: 2})

Mysql weird storage

mysql> select * from notification_requests;
+----+----------+------+----------------+-------------------------+-----------+---------------------+---------------------+
| id | order_id | key  | details        | type                    | status    | created_at          | updated_at          |
+----+----------+------+----------------+-------------------------+-----------+---------------------+---------------------+
|  7 |       19 | NULL | "---\n:a: 2\n" | PushNotificationRequest | INITIATED | 2019-01-09 13:45:40 | 2019-01-09 13:45:40 |
+----+----------+------+----------------+-------------------------+-----------+---------------------+---------------------+

The details column is stored as some weird string and not a proper json I am using mysql 8.0.12 and rails 5.12

Is there something I am missing?

t0il3ts0ap
  • 530
  • 4
  • 18

2 Answers2

3

According to the docs Keep in mind that database adapters handle certain serialization tasks for you. For instance: json and jsonb types in PostgreSQL will be converted between JSON object/array syntax and Ruby Hash or Array objects transparently. There is no need to use serialize in this case.

serialize :details was not required and was corrupting the serialization in a way. After removing, got the correct json in mysql.

t0il3ts0ap
  • 530
  • 4
  • 18
0

I think you need to define to specifically serialize the attribute as JSON in this case:

class PushNotificationRequest < ApplicationRecord
  serialize :details, JSON

Are you sure that MySQL is able to store JSON by the way? (I'm only experienced with PostgreSQL)

bo-oz
  • 2,842
  • 2
  • 24
  • 44
  • I tried that earlier. It gives ```ActiveRecord::AttributeMethods::Serialization::ColumnNotSerializableError: Column `details` of type ActiveRecord::Type::Json does not support `serialize` feature. Usually it means that you are trying to use `serialize` on a column that already implements serialization natively.``` – t0il3ts0ap Jan 09 '19 at 14:39
  • 1
    Ya mysql has json support since 5.7 – t0il3ts0ap Jan 09 '19 at 14:44
  • 1
    Strange, it's in the docs: https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html. What happens when yopu retrieve the record, although it has a strange value in the database, it might be that Rails is able to retrieve it correctly as a JSON object.] – bo-oz Jan 09 '19 at 14:53
  • 2
    Ohh in the doc it says you dont need `serialize` at all, if the column is `json`. It works, thanks for the doc – t0il3ts0ap Jan 09 '19 at 15:07