Search code examples
ruby-on-rails-4hstore

Using hstore and saving new values for user


My user model contains values for things like:

name, email, phone, approved, etc..

The scope of the project I am working on includes custom user settings and for this reason I am using hstore (I dont want to create a user_settings table).

On the user edit view I want to create a checkbox called 'colors' and whether or not the checkbox is checked determines if that setting is set for the user or not.

I have already setup hstore as follows:

class AddHstore < ActiveRecord::Migration
  def up
    enable_extension :hstore
  end

  def down
    disable_extension :hstore
  end
end

And updated the User model as follows:

class AddSettingsToUser < ActiveRecord::Migration
  def up
    add_column :users, :settings, :hstore
  end

  def down
    remove_column :users, :settings
  end
end

This is essentially my user edit view:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, :class => "form-horizontal user" }) do |f| %>
  <%= devise_error_messages! %>

      <div class="field">
        <%= f.label :name %><br />
        <%= f.text_field :name, autofocus: true %>
      </div>

      <div class="field">
        <%= f.label :email %><br />
        <%= f.email_field :email %>
      </div>

      <div class="field">
        <%= f.label :phone_number %><br />
        <%= f.text_field :phone_number %>
      </div>

      <div class="actions">
        <%= f.submit 'Update', :class => 'btn btn-primary' %>
      </div>

<% end %>

At this point I am unsure as to how to actually implement this functionality. The user edit page allows the user to change their name, phone and other values but how would I include a new value for the hstore settings?


Solution

  • Inside the form_for from where you are creating users, add your hstore fileds like below :

    <%= form_for resource, ...do |f| %>
      #...
      <%= f.fields_for :settings do |settings| %>
        <%= settings.text_field :field1 %>
        <%= settings.text_field :field2 %>
      <% end %>
      #....
    <% end %>
    

    Then update your controller strong parameter method like below to permit these new fields.:

      def user_params
           params.require(:user)
                 .permit(
                          :name,
                          :email,
                          settings: [ :field1, :field2 ]
                        )
      end
    

    Now, you are done. Open your rails console and try some sample data like

    User.create(
                settings: { field1: 'data1', field2: 'data2' }
               )