Hugo
Hugo

Reputation: 2204

Getting weird format when trying to update rails column array type

I'm trying to update a column called needs that is the following:

t.text "needs", default: "{}"

I went through a couple migration to try and make it work and I still get the same error. It does not update the column and it looks like it reformats the data inside my api call. Here is what I get from the rails server:

Parameters: {"user"=>{"birthdate"=>"2019-07-30T11:59:31.215Z", "needs"=>["relationship", "life", "general"], "coach_gender"=>""}, "id"=>"15"}

UPDATE "users" SET "needs" = $1, "updated_at" = $2 WHERE "users"."id" = $3  [["needs", "[\"relationship\", \"life\", \"general\"]"], ["updated_at", "2019-07-30 12:08:12.013589"], ["id", 15]]

Then when I try do get the first need from the user like so:

User.needs.first

I get

"["

My controller looks like this:

def edit
  User.find_by(id: params[:id]).update_attributes(user_params)
end

def user_params
  params.require(:user).permit(:first_name, :last_name, :birthdate, :description, :email, :password, :coach_gender, :needs => [])
end

Upvotes: 1

Views: 67

Answers (2)

jvillian
jvillian

Reputation: 20263

Why do you think it is weird to get "[" when doing User.needs.first? User.needs holds text and the first character of your sample text is "[". Seems perfectly normal.

What seems weird (to me) is that you're using a text datatype to store an array without any serialization. Or, alternatively, using a native array datatype (as with PostgreSQL) doing something like:

t.string 'needs', array: true

...in your migration (see the guide for more information).

It also seems weird (to me) that the default for the supposed array appears to be a hash (default: "{}").

I also wonder why you're not using a Need model and creating a M:M relationship between User and Need. Something, perhaps, like:

# == Schema Information
#
# Table name: needs
#
#  id               :bigint           not null, primary key
#  name             :string
#  created_at       :datetime         not null
#  updated_at       :datetime         not null
#
class Need < ApplicationRecord
  has_many :user_needs
  has_many :users, through: :user_needs
end

# == Schema Information
#
# Table name: user_needs
#
#  id               :bigint           not null, primary key
#  user_id          :integer
#  need_id          :integer
#  created_at       :datetime         not null
#  updated_at       :datetime         not null
#
class UserNeed < ApplicationRecord
  belongs_to :user
  belongs_to :need
end

class User < ApplicationRecord
  has_many :user_needs
  has_many :needs, through: :user_needs
end

Which will make querying easier down the road. Like, "give me all users that have a life need" could be something like:

Need.find_by(name: 'life').users

Upvotes: 2

udnpico
udnpico

Reputation: 3

It should be

t.text "needs", array: true,  default: "{}"

Upvotes: 0

Related Questions