I’m writing a simple blog app in Rails, version 3.2.8. I’ve scaffolded the “posts” resource as follows:
rails g scaffold post title:string body:string islive:boolean
I want to set islive to be false by default and I’m trying to do so in my model. I also decided I don’t want it available to mass assignment so I’ve coded up my model as follows:
class Post < ActiveRecord::Base
attr_accessible :body, :title
before_save :default_values
def default_values
self.islive = false
end
end
I’ve also removed the islive field from my form. The trouble is when I try to create a new post with the model as above, it doesn’t save. The console looks like this:
Started POST "/posts" for 127.0.0.1 at 2012-10-14 18:23:30 +0100
Processing by PostsController#create as HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"/lNa21JBeBz/H2cYLqAsF8uWr1frLV88WsOVKzOqwb4=", "post"=>
{"title"=>"sample title", "body"=>"the body"}, "commit"=>"Create Post"}
(0.1ms) begin transaction
(0.0ms) rollback transaction
Rendered posts/_form.html.erb (1.8ms)
Rendered posts/new.html.erb within layouts/application (2.5ms)
Completed 200 OK in 29ms (Views: 26.3ms | ActiveRecord: 0.1ms)
And nothing is saved. I simply get the begin transaction rollback transaction However, if I change default_values to this:
def default_values
self.islive = 'false'
end
everything works and it saves fine, with a falsey value for islive. Even if I just do something like this:
def default_values
self.islive = false
Rails.logger.debug self.islive
end
then the save works.
Can somebody shed some light on why this behaves as it does?
before_saveand other callbacks terminate saving if they returnfalse. This is exactly what you did. It’s a trap if you forget about it. You can put sometrue(or evennil) at the very last line: