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

1

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

4 Comments

hmm it is turned now into an array, but when I want to add array of integers I get an error: ActiveRecord::SerializationTypeMismatch (can't dump gateways: was supposed to be a Array, but was a Integer. -- 0)
You need to explicitly tell rails to expect for an array
This error raised when unserialized object’s type mismatches one specified for serializable field. So check the type of your object.
Change your column's datatype to text.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.