0

In my app I've got a table named contacts with the areas_of_interest field. This field should store hashes sent by user via form. However my database reject those hashes and leave this field blank every time when I want to save it:

Schema:

create_table "contacts", force: :cascade do |t|
  ...
  t.text "areas_of_interest"
  t.index ["user_id"], name: "index_contacts_on_user_id"
end

Contact Model:

class Contact < ApplicationRecord
  belongs_to :user        
  serialize :areas_of_interest
  ...
end

ContactsController:

def update
  respond_to do |format|
    if @contact.update(contact_params)
      format.html do
        redirect_to root_path, notice: 'Contact has been updated'
      end
    else
      format.html do
        render :edit, notice: 'Error'
      end
    end
  end
end

private

def contact_params
  params.require(:contact).permit(
    ...
    :areas_of_interest,
    ...
  )
end

And the hash sent from client looks like this:

{"first"=>"1", "second"=>"0", "third"=>"0", "fourth"=>"0", "fifth"=>"1"}

What possibly do I do here wrong and how can I fix it?

4
  • change :areas_of_interest to areas_of_interest: {} Commented Mar 14, 2019 at 21:53
  • Where? In Model? Commented Mar 14, 2019 at 21:54
  • in params.require(:contact).permit(... Commented Mar 14, 2019 at 22:00
  • 2
    If you have postgres - use jsonb or hstore data type. Commented Mar 14, 2019 at 22:38

2 Answers 2

1

Your format appears to be a dump of a Ruby Hash. serialize is done using YAML. It would look like this.

{ first: "1", second: "0", third: "0", fourth: "0", fifth: "1"}

But there's a better way. Since you're using Postgres you can take advantage of Postgres JSONB and send the data as JSON. The serialization will be handled for you, you have all the power of Postgres's JSON search facilities, and JSON is a standard format that most languages can produce.

{ "first": "1", "second": "0", "third": "0", "fourth": "0", "fifth": "1"}

create_table "contacts", force: :cascade do |t|
  ...
  t.jsonb :areas_of_interest
  t.index [:areas_of_interest], using: :gin
end

Nothing special is needed in Contact. Use contact.areas_of_interest like any other field, but it can take Hashes and Arrays.

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

Comments

1

areas_of_interest looks like it's getting filtered out by strong_params. I think what you need is something like this to indicate which keys should be allowed:

params.require(:contact).permit(
  ...
  areas_of_interest: [:first, :second, :third, :fourth, :fifth],
  ...
)

I also highly recommend using the jsonb type as mentioned by @Schwern.

Comments

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.