Maxime
Maxime

Reputation: 357

How to store an array in a User model in a Ruby-On-Rails application?

I am trying to save an array of strings in a column of my table users. I have this line in my migration file add_column :users, :choices, :string. This doesn't work as I am trying to store an array and not just a string, my terminal shows Unpermitted parameter: :choices. How can I store an array ?? (Obviously add_column :users, :choices, :array doesn't work.)

Upvotes: 3

Views: 3121

Answers (2)

max
max

Reputation: 102045

The database column really has nothing to do with the error. You define array columns by defining a type and using the array: true option as arrays are typed in most databases unlike in Ruby:

add_column :users, :choices, :string, array: true

However this is usually a bad idea as you're violating first normal form (1NF) by putting multiple values in one column and giving up all the advantages that having a discrete table has in terms of normalization, assocations, foreign keys etc. This is idea that everyone entertains when they discover array columns - but is not really a good design decision.

Unpermitted parameter: :choices is raised when you pass an ActionController::Parameters instance with an unpermitted key. It has absolutely nothing to do with the underlying database column or the attribute.

You can whitelist array columns by passing a hash key with an empty array:

params.require(:user)
      .permit(:foo, :bar, choices: [])

This permits an array containing any type of permitted scalar value.

Upvotes: 3

lacostenycoder
lacostenycoder

Reputation: 11226

Should be as simple as this in your migration

  def change
    add_column :users, :choices, :string, array: true
  end

Then you probaly want to prevent writing non-array types.

#app/models/users.rb

  def choices=(input)
    raise TypeError, 'choices must be an array' unless input.is_a?(Array)
    super
  end

Upvotes: 0

Related Questions