2

I have one PostgreSQL table which I want to transform to MySql in my Rails app. Main thing is that gateways column won't transform into an 'array' column. It looks like this in schema.rb:

create_table "settings", force: :cascade do |t|
    t.integer "gateways", default: [], array: true
    t.integer "name"
    t.integer "lastname"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

When I run this migration(after installing MySql gem):

class CreateSettings < ActiveRecord::Migration[5.2]
  def change
    create_table :settings do |t|
      t.integer gateways, array: true, default: []
      t.string :name
      t.string :lastname
      t.timestamps
    end
  end
end

I got, in my schema.rb, table which hasn't default: [] and array: true values:

create_table "settings", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.integer "gateways"
    t.integer "name"
    t.integer "lastname"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

And if I want to add values for gateways in console:

>Setting.first.gateways = [1,2,3]

I always get nil as a result

>Setting.first.gateways
>nil

I tried also with serialize :gateways in my Setting.rb model but that also don't work

Any ideas?

Edit: It's not same as this question because it is an explanation for PostgreSQL database, not MySql

goldie
  • 77
  • 1
  • 10
  • Possible duplicate of [Add an array column in Rails](https://stackoverflow.com/questions/32409820/add-an-array-column-in-rails) – Eyeslandic Apr 29 '19 at 22:49

2 Answers2

3

That would have worked for Postgres - but MySQL does not have a native array type (at the time of writing).

It does have JSON columns which can be used to store arrays. Or you can create a separate table and model for gateways and just join it like any other association.

serialize is an old hack that uses a varchar/text column. It encodes the attributes contents as YAML and stores the resulting string. Its not appropriate here.

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.

max
  • 96,212
  • 14
  • 104
  • 165
1

The way things like that are done is with serializing the array. You can try ActiveRecord::Base.serialize. The serialization is done through YAML.

To do so, you must specify this with a call to the class method serialize. This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work.

class User < ActiveRecord::Base
  serialize :preferences
end

user = User.create(preferences: { "background" => "black", "display" => large })
User.find(user.id).preferences # => { "background" => "black", "display" => large }

In your case, you can try as

class Setting < ActiveRecord::Base
  serialize :gateways, Array
end
shrikant1712
  • 4,336
  • 1
  • 24
  • 42