Mateo Acebedo
Mateo Acebedo

Reputation: 45

Ruby on Rails create method not saving parameters

My create method is not working and it used to work. Thanks in advance!

<%= form_for :category, url: categories_path do |f| %>
    <p>
      <%= f.label :title %><br>
      <%= f.text_field :title %>
    </p>

    <p>
      <%= f.submit %>
    </p>
<% end %>

my controller:

class CategoriesController < ApplicationController
  def show
    @category = Category.where(id: params[:id]).first
  end

  def create
    @category = Category.create(title: params[:category][:title])
    redirect_to @category
  end
end 

Note: params[:category][:title] is in fact the correct value

my model:

class Category < ActiveRecord::Base
  has_many :events

  attr_accessor :title
end

my migration:

class CreateCategories < ActiveRecord::Migration
  def change
    create_table :categories do |t|
      t.string :title

      t.timestamps
    end
  end
end

And when I go to my form and input "main" (or anything else) in the text box and then click save It is saved in my database as:

 id | title |      created_a      |     updated_at      |
---------------------------------------------------------
 1  | NULL  | 2013-11-16 21:30:59 | 2013-11-16 21:30:59 |

As you can see I am not being able to save my parameter in the database. This was not happening to me before, I went and tried to make some changes to my structure and this issue started happening so I reverted and now it does not even work even though I reverted. By the way I am using a mysql database. Thanks in advance!

Upvotes: 3

Views: 5485

Answers (4)

AndyV
AndyV

Reputation: 3741

While Rails 4 does favor strong parameters, it requires a developer action to enable them. First, the developer has to include a module in the model to turn them on:

include ActiveModel::ForbiddenAttributesProtection

Without that include using the require/permit pair that many here have mentioned has no negative effect. (The converse is not true -- if you include the module but do not sanitize the params using require/permit then you'll get an error).

Mateo's problem is much simpler. In the Category class definition you have included

attr_accessor :title

That's good form for Ruby... but not with Rails. The attr_accessor macro creates a getter/setter pair for an attribute named 'title' on the class. Unfortunately, that means that the inherited code from ActiveRecord will not create the magic methods that shuttle the title attribute to/from the database. Remove the attr_accessor for title and you'll be in business.

class Category
  has_many :events
end

Upvotes: 6

Dmitry Landberg
Dmitry Landberg

Reputation: 36

It's better to use a separate method to permit params.

private
  def category_params
    params.require(:category).permit(:title)
  end

And then in the create method:

@category = Category.create(category_params)

Upvotes: 1

strivedi183
strivedi183

Reputation: 4831

As @CDub said in his answer, in Rails 4, you have to use strong parameters so an example would be

class CategoriesController < ApplicationController
  def show
    @category = Category.where(id: params[:id]).first
  end

  def create
    @category = Category.create(params.require(:category).permit(:title))
    redirect_to @category
  end
end

And in your model you could remove attr_accessible

class Category < ActiveRecord::Base
  has_many :events
end

Upvotes: 1

CDub
CDub

Reputation: 13354

If you upgraded to Rails 4, Rails 4 now favors strong parameters in place of attr_accessible and attr_protected. It's likely that your parameters are being blacklisted because of Rails 4 defaulting to use strong parameters.

Check out this gem with details on upgrading from Rails 3 to Rails 4, and the documentation for differences between Rails 3 and Rails 4.

Upvotes: 0

Related Questions