Rails Bug: Saving Only "changed" Attributes Hurts Serialization

Posted by John Wulff Sat, 09 Aug 2008 02:10:00 GMT

Really unhappy with this bug. I hope the Rails team agrees that this is a bug unlike my last “bug” report.

If you’re unfarmiliar with “changed?” attribute updating I recommend reading Living on the edge (of Rails) #14 before continuing.

Here it is, the nasty:

class Node < ActiveRecord::Base
  serialize :data
end
>> n = Node.create! :data => { :a => 1 }
=> #<Node id: 417950, data: {:a=>1}>
>> n.id
=> 417950
>> m = Node.find 417950
=> #<Node id: 417950, data: {:a=>1}>
>> m.data[:b] = 2
=> 2
>> m
=> #<Node id: 417950, data: {:b=>2, :a=>1}>
>> m.changed?
=> false
>> m.save!
=> true
>> m = Node.find 417950
=> #<Node id: 417950, data: {:a=>1}>

Changes to the hash are never saved and that makes me really, really sad.

I’ve opened a ticket.

Rails validates_presence_of Strangeness

Posted by John Wulff Tue, 16 May 2006 02:53:00 GMT

I found an annoying bug in validates_presence_of, it does not like booleans.

class CreateNodes < ActiveRecord::Migration
  def self.up
    create_table :nodes do |t|
      t.column :boolean_var, :boolean, :default => 0
    end
  end
end
class Node < ActiveRecord::Base
  validates_presence_of :boolean_var
end
class NodeTest < Test::Unit::TestCase
  def test_boolean_var
    node = Node.new
    node.boolean_var = 0
    node.save!
  end
end
  1) Error:
 test_boolean_var(NodeTest):
 ActiveRecord::RecordInvalid: Validation failed: Boolean var can't be blank
 /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record/validations.rb:736:in
 `save!'
    /Users/jwulff/Development/NodeTestApp/test/unit/node_test.rb:5:in
 `test_boolean_var'

 1 tests, 0 assertions, 0 failures, 1 errors

Blake Watters gave me this workaround.

validates_inclusion_of :boolean_var, :in => [true, false]

I’ve opened a ticket at dev.rubyonrails.org

UPDATE: The ticket has been closed as invalid. Manfred says:

validates_presence_of behaves exactly as documented. Please use {{{validates_inclusion_of :boolean_var, :in => [true, false]}} as the first commenter suggested.