3

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!

1
  • 1
    Did you just upgrade to Rails 4? Commented Nov 16, 2013 at 21:50

4 Answers 4

6

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
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

1

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)

Comments

0

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.

1 Comment

While true, the models would have to include the ForbiddenAttributesProtection module for strong params to have an effect. See below.

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.