{"id":20,"date":"2006-09-22T00:39:41","date_gmt":"2006-09-22T08:39:41","guid":{"rendered":"http:\/\/blog.danielparnell.com\/?p=20"},"modified":"2006-09-22T01:27:51","modified_gmt":"2006-09-22T09:27:51","slug":"before_create-considered-harmful","status":"publish","type":"post","link":"https:\/\/blog.danielparnell.com\/?p=20","title":{"rendered":"before_create considered harmful"},"content":{"rendered":"<p><span style=\"font-size: 12pt; font-family: Helvetica\">I had a fsck of a time today working with rails.  Normally I love Ruby on Rails, but today it gave me the screaming shifts!<\/p>\n<p>I had a model class to which  I wanted to add some sensible default values to satisfy some constraints in the database.<br \/>\nThe logical place for that was before_create, so I did something like the following<\/p>\n<p><\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">class<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\"> MyModel &lt; ActiveRecord::Base<br \/>\n<\/span><\/p>\n<blockquote><p><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">def<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\"> before_create <\/span><br \/>\n<span style=\"font-size: 10pt; font-family: Monaco,monospace\">        <\/span><\/p>\n<blockquote><p><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">self<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\">.foo ||= <\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">true<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\"> <\/span><br \/>\n<span style=\"font-size: 10pt; font-family: Monaco,monospace\">        <\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">self<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\">.bar ||= Time.now <\/span><br \/>\n<span style=\"font-size: 10pt; font-family: Monaco,monospace\">        <\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">self<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\">.baz ||= <\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">false<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\"> <\/span><\/p><\/blockquote>\n<p><span style=\"font-size: 10pt; font-family: Monaco,monospace\">    <\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">end<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\"> <\/span><br \/>\n<span style=\"font-size: 10pt; font-family: Monaco,monospace\" \/><\/p><\/blockquote>\n<p><span style=\"font-size: 10pt; font-family: Monaco,monospace; color: #0000cc\">end<\/span><span style=\"font-size: 10pt; font-family: Monaco,monospace\"><br \/>\n<\/span><span style=\"font-size: 12pt; font-family: Helvetica\"><br \/>\nNow, I would have thought that would work, but whenever I tried to save an instance of my class to the database the save method would return false \ud83d\ude41<br \/>\nHmmmm.  Ok, let&#8217;s add some logging code and see what the problem is&#8230; Are there any errors?  Nope.  Does the instance think it&#8217;s valid?  Yes.  OK, that&#8217;s weird.  Maybe there is something going on and the exception is getting eaten by some other code in the application (there are three of us working on this code and we&#8217;re not all in the same state, so who knows what one of the others may have done \ud83d\ude09 ).  I try creating an instance using the rails console.  Same thing (which is to be expected, but I was starting to get a little desperate by this stage).<\/p>\n<p>What was the next thing to do?  Go through the code and remove things line by line until I start getting some exceptions.  Finally in desperation I took out my before_create method, and lo and behold my error messages come back.  It was then that I was struck by the thought that Ruby methods take their return value from the last expression evaluated in their body, so the before_create method was returning false.  It seems that there is a nice undocumented &#8220;feature&#8221; in ActiveRecord that allows application code to stop an object being saved to the database by returning false from before_create, and I imagine before_save.<\/p>\n<p>A little note to that affect in the documentation would have saved me quite a bit of time today.<\/p>\n<p>Ah well.  Live and learn I guess \ud83d\ude42<br \/>\n<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I had a fsck of a time today working with rails. Normally I love Ruby on Rails, but today it gave me the screaming shifts! I had a model class to which I wanted to add some sensible default values to satisfy some constraints in the database. The logical place for that was before_create, so &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.danielparnell.com\/?p=20\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;before_create considered harmful&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[2,8,6],"tags":[],"class_list":["post-20","post","type-post","status-publish","format-standard","hentry","category-programming","category-rails","category-web","entry"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p561S3-k","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=\/wp\/v2\/posts\/20","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=20"}],"version-history":[{"count":0,"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=\/wp\/v2\/posts\/20\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=20"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=20"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.danielparnell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=20"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}