Search code examples
mysqlrubydatabaseruby-datamapperenumerated-types

DataMapper enum field doesn't persist when saved or updated


I am trying to map a legacy MySQL database with a fresh DataMapper model.

MySQL schema:

CREATE TABLE IF NOT EXISTS `backer` (
  `backer_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `secret` varchar(16) NOT NULL,
  `email` varchar(255) DEFAULT NULL,
  `status` enum('pending','ready') NOT NULL DEFAULT 'pending',  # relevant bit
  PRIMARY KEY (`backer_id`),
  UNIQUE KEY `backer_id` (`secret`),
  KEY `email` (`email`,`status`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8166 ;

DataMapper model:

class Backer
  include DataMapper::Resource
  storage_names[:default] = "backer"     

  property :id,      Serial, :field => "backer_id"
  property :secret,  String, :field => "secret"
  property :email,   String, :field => "email"
  property :status,  Enum[ :pending, :ready ], :field => "status", :default => "pending"
  has n, :items, :child_key => "backer_id"
end

DataMapper.finalize

With most attributes, I can persist:

b = Backer.first
b.first_name = "Daniel"
b.save!
# Backer.first.first_name == "Daniel"

It persists fine. But when I do it with an enum:

b = Backer.first
b.status = :pending
b.save!

# b.status == :pending
# Backer.first.status != :pending
# Backer.first.update!(:status => :pending) ... 

Updates/saves to an enum field doesn't seem to persist it.

SQL looks typically like:

1.9.3p327 :019 > Backer.last.update(:status => :ready)
 ~ (0.000349) SELECT `backer_id`, `secret`, `email`, `status` FROM `backer` ORDER BY `backer_id` DESC LIMIT 1
 ~ (0.000190) UPDATE `backer` SET `status` = 2 WHERE `backer_id` = 8166
 => true

But when I view the object (e.g. Backer.last) then status is not changed.

UPDATE

I've verified that the enumerated status field in the MySQL database is being persisted. However, the enumerated status property in the DataMapper class doesn't reflect this at all (is always nil).

What's happening here?


Solution

  • Thanks @morbusg: that's one solution.

    The other one was to change the Enum at my end to a String and that's worked fine for my purposes.