Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

How would you insert values from a form into an array in the database? I'm using simple form, rails 4.1, postgresql db.

Here is my form, all fields update correctly except for the impact and likelihood fields (both arrays). They are the focus of this question:

<%= simple_form_for(@risk) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="form-group">
    <%= f.input :title, required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-group">
    <%= f.input :description, required: false, :error => false,  as: :text, input_html: { class: 'form-control description' } %>
  </div>

  <div class="form-group">
    <%= f.input :area, :collection => ['Operations', 'IT', 'Finance'], required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-group">
    <%= f.input :owner, :collection => User.all, required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-group">
    <%= f.input :action, required: false, :error => false, input_html: { class: 'form-control' } %>
  </div>

  <div class="form-inline">
    <span class="date-of-action-input">
    <%= f.input :date_of_action, :as => :date, :start_year => Date.today.year - 10, :end_year => 2030,
        :order => [ :day, :month, :year], :required => false, :error => false, input_html: { class: 'form-control' } %>
    </span>
    <span class="action-completed-input">
    <%= f.input :action_completed, as: :boolean, required: false, :error => false, input_html: { class: 'form-control' } %>
    </span>

    <span class="impact-input">
    <%= f.input :impact, required: false, :error => false, input_html: { class: 'form-control' } %>
    </span>
    <span class="likelihood-input">
    <%= f.input :likelihood, required: false, :error => false, input_html: { class: 'form-control' } %>
    </span>
    <span class="submit-risk">
    <%= f.button :submit, :error => false, :error => false, input_html: { class: 'form-control' } %>
    </span>
  </div>
<% end %>

Here the associated controller (risks_controller.rb):

class RisksController < ApplicationController
before_action :signed_in_user
before_action :correct_user, only: [:destroy, :update]


def create
    @risk = current_user.risks.build(risk_params)
    if @risk.save
      flash[:success] = "Risk created!"
      redirect_to root_url
    else
      render 'new'
    end
end

def new
  @risk = Risk.new
end

def destroy
  @risk.destroy
  redirect_to root_url
end

def edit
  @risk = Risk.find(params[:id])
end

def update
  @risk = Risk.find(params[:id])
    @risk.assign_attributes(risk_params)
    if @risk.changed? == false
      flash[:info] = "No changes were made"
      redirect_to root_url
    elsif @risk.update_attributes(risk_params)
      flash[:success] = "The risk has been updated."
      redirect_to root_url
    else
        render 'new'
    end
end

private

    def risk_params
        params.require(:risk).permit(:description, :title, :area, :owner, :action, :date_of_action, :action_completed, :impact, :likelihood)
    end

  def correct_user
    if current_user.admin?
      @risk = Risk.find_by(id: params[:id])
      redirect_to root_url if @risk.nil?
    else
      @risk = current_user.risks.find_by(id: params[:id])
      redirect_to root_url if @risk.nil?
    end
  end

end

My db schema file:

ActiveRecord::Schema.define(version: 20140617165640) do

  create_table "risks", force: true do |t|
    t.integer  "user_id"
    t.string   "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "title"
    t.string   "area"
    t.string   "owner"
    t.string   "action"
    t.date     "date_of_action"
    t.boolean  "action_completed", default: false
    t.integer  "impact",           default: [],    array: true
    t.integer  "likelihood",       default: [],    array: true
  end

  add_index "risks", ["user_id", "created_at"], name: "index_risks_on_user_id_and_created_at", using: :btree

  create_table "users", force: true do |t|
    t.string   "name"
    t.string   "email"
    t.boolean  "admin",           default: false
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "password_digest"
    t.string   "remember_token"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["remember_token"], name: "index_users_on_remember_token", using: :btree

end

I imagined the code would look something like this, but alas, my first rails project and I need a bit of guidance. In risks_controller.rb:

def create
  @risk = current_user.risks.build(risk_params)
  @impact = risk_params[:impact]
  @userid = current_user.id
  @impacttoupdate = Risk.select(:impact).where(id: risk_params[:id])
  @impacttoupdate.insert(@userid, @impact)
    if @risk.save
      flash[:success] = "Risk created!"
      redirect_to root_url
    else
      render 'new'
    end
end

I want to insert the value according to the user id. So if the user id is 3, the value from the form they are submitting should go into the 3rd slot in the array.

share|improve this question

1 Answer 1

You have to define in strong params that post values are arrays.

def risk_params
    params.require(:risk).permit(:description, :title, :area, :owner, :action, :date_of_action, :action_completed, {:impact => []}, {:likelihood=>[]})
end
share|improve this answer
    
Thanks for your help. While I'm sure it's a valid correction it hasn't solved the issue. New risks are still getting created with all the other fields populated but the impact and likelihood fields turning up as '[]'. I checked the db in the console using Risk.all to confirm it wasn't anything to do with my views. :( –  Chris Butcher Jun 18 at 13:38
    
Are you serializing the fields in the model? –  Ruby Racer Jun 18 at 14:32
    
I hadn't, but I have looked into it and added the lines 'serialize :impact' and 'serialize :likelihood' in risk.rb model. I'm now hit with a different error: PG::InvalidTextRepresentation: ERROR: array value must start with "{" or dimension information : INSERT INTO "risks" ("action", "area", "created_at", "date_of_action", "description", "impact", "likelihood", "owner", "title", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id". Any ideas? Thank you for your help thus far btw, appreciate it. –  Chris Butcher Jun 18 at 16:49
    
You'll probably need to generate some migrations to fix your schema. I can't do it for you, but I'd suggest you took a look to the array column type: How to define the field, how to manage it in the model and how to manipulate data in the controller. It's all there, in one page. Play around it and you'll be able to troubleshoot it quite easily I believe –  Ruby Racer Jun 18 at 19:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.