Skip to content

Instantly share code, notes, and snippets.

@compactcode
Last active December 14, 2015 15:08
Show Gist options
  • Save compactcode/5105152 to your computer and use it in GitHub Desktop.
Save compactcode/5105152 to your computer and use it in GitHub Desktop.
Rails fun with a not null constraint and a default value.
class CreateCustomers < ActiveRecord::Migration
def change
create_table :customers do |t|
t.string :name, :null => false
t.boolean :subscribed, :null => false, :default => true
t.timestamps
end
end
end
curl --data "customer[name]=shanon" http://localhost:3000/customers.json => 200
curl --data "customer[name]=shanon&customer[subscribed]=0" http://localhost:3000/customers.json => 200
curl --data "customer[name]=shanon&customer[subscribed]=" http://localhost:3000/customers.json => 500
Customer.create!(:name => "shanon") => #<Customer id: 1 ... >
Customer.create!(:name => "shanon", :subscribed => nil) => ActiveRecord::StatementInvalid
Customer.create!(:name => "shanon", :subscribed => "") => ActiveRecord::StatementInvalid
class Customer < ActiveRecord::Base
attr_accessible :name, :subscribed
end
class CustomersController < ApplicationController
respond_to :json
def create
respond_with Customer.create(params[:customer])
end
end
@mipearson
Copy link

how's that bad? you've deliberately specified 'nil' in the create statement. If you want to work around it in a way that doesn't throw an exception on save (but will on save!) add validates_presence_of :subscribed to your model.

@compactcode
Copy link
Author

I'm setting this value from parameters which means that during a rolling deploy, old forms will submit nulls. Also it would be nice if I didn't have to update all the specs, features and fixtures with this parameter,

Customer.create!(
  :subscribe => params[:subscribe]
)

@cmaitchison
Copy link

Add this to your model as an interim step

before_save :set_default_subscribed

def set_default_subscribed
    self.subscribed = true if self.subscribed.nil?
end

beware that this won't work

self.subscribed ||= true

@compactcode
Copy link
Author

@cmaitchison yeah that works nicely. Feels like I'm fighting rails though and life would be a lot easier if I just removed the not null constraint.

@mipearson
Copy link

Forms don't submit nulls: nulls get stripped from the incoming params by Rails. Assuming HTTP GET/POST and not JSON/XML, that is.

@mipearson
Copy link

Oh. Wait. Yeah, I think I get it - something else is pulling it from a form params, and it's defaulting to null. Yeah. Workaround, then remove post deploy.

@mipearson
Copy link

But that's not a bug :p

@keithpitt
Copy link

Shouldn't rails be calling to_bool when you model.this_attribute_is_a_boolean = ""?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment