Jbur43
Jbur43

Reputation: 1312

"Simple Form" data not inserting into database

I have a form that looks like this

<%= simple_form_for @contact_form, url: contact_form_index_path, method: :post do |f| %>
    <%= f.input :first_name, placeholder: 'Jane' %>
    <%= f.input :last_name, placeholder: 'Doe' %>
    <%= f.input :email, placeholder: '[email protected]' %>
    <%= f.input :address, placeholder: '123 Main Street' %>
    <%= f.input :city, placeholder: 'Pleasantville' %>
    <%= f.input :state, placeholder: 'NJ' %>
    <%= f.input :zip_code, placeholder: '12345' %>
    <%= f.input :phone, placeholder: '(123) 456-7890' %>
    <%= f.button :submit %>
<% end %>

My db schema looks like this;

create_table "contact_forms", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.string   "email"
    t.string   "address"
    t.string   "city"
    t.string   "zip_code"
    t.string   "state"
    t.integer  "phone"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

My controller looks as follows;

class ContactFormController < ApplicationController
    def new
        @contact_form = ContactForm.new
    end

    def create
        @contact_form = ContactForm.new

        if @contact_form.save
            redirect_to pages_url
        else
            render :new
        end
    end
end

When I test out the form and try to post the entered data into my database, I do not receive an error, but the data is not populated into the table.

Do you know what could be causing this? Below are the logs, if it helps.

 Parameters: {"utf8"=>"✓", "authenticity_token"=>"IniAUnB4O51+1KrNy5Ip/nVPqmEZaXopoFozaBu98bkvg0MP5GxbEkzKKltY/QuVomxE2hnDT7cIloy99u0Nsw==", "contact_form"=>{"first_name"=>"Jack", "last_name"=>"Burum", "email"=>"", "address"=>"", "city"=>"", "state"=>"", "zip_code"=>"", "phone"=>""}, "commit"=>"Create Contact form"}
   (0.1ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "contact_forms" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2015-11-27 18:37:45.421056"], ["updated_at", "2015-11-27 18:37:45.421056"]]
   (7.3ms)  commit transaction
Redirected to http://localhost:3000/pages
Completed 302 Found in 11ms (ActiveRecord: 7.7ms)

Upvotes: 0

Views: 916

Answers (2)

Jon
Jon

Reputation: 10898

When using mass assignment to create a record, Rails will throw an error if the params have not been permitted by your controller. This is intended to stop people injecting things into your database that you aren't expecting.

Imagine you have a signup form, and you want to accept just a name and an email address from the user, but also consider that you have a column on your table called is_admin.

Normally, your form submits the :name and :email in your params hash from the form, but imagine for a moment that an attacker constructs their own POST request and inserts :is_admin => true along with the rest of the data. Clearly you want your controller to ignore that part of the request!

So, in steps Strong Parameters. With this enabled (it is by default), you must explicitly permit the elements of the params hash you are willing to accept. In the case above, you'd use something like this:

params.require(:user).permit(:name, :email)

Which will require there to be a :user element within params, and will allow the :user to provide a :name and :email but nothing more.

However, using that in lots of places in your controller quickly becomes annoying when you have to change the permitted parameters, hence it's typical to place it in a private method and reference it from there:

private

def user_params
  params.require(:user).permit(:name, :email)
end

Then, you can simply call your user_params method anywhere in your controller where you need to use them!

So, in your case (as you have already realised), you should create a private method which should return the permitted params you're willing to accept, and use that method when creating your model records.

Upvotes: 2

Jbur43
Jbur43

Reputation: 1312

So I needed to add a private method that I called 'contact params'. In this method I permitted access to the data I needed in my form.

I still am not 100% clear as to why you need to permit data attributes when you want the create method to have access to all of the data.

It works now.

Upvotes: 0

Related Questions