Reputation: 45
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
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
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
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
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