Как я могу прозрачно изменить метод ActiveRecord в модели? - PullRequest
6 голосов
/ 08 февраля 2010

У меня есть модель с UUID, хранящимися в поле BINARY (16) в таблице MySQL. Я хотел бы иметь возможность прозрачно преобразовать шестнадцатеричный uuid в двоичный файл для метода setter и обратно, когда я использую метод getter.

каков правильный путь?

Ответы [ 2 ]

7 голосов
/ 09 февраля 2010

Вы переопределяете установщик и получатель:

class User < ActiveRecord::Base
  def uuid=(value)
    @uuid = write_attribute(:uuid, value.scan(/../).map {|n| n.to_i(16)}.pack("C*"))
  end

  def uuid
    @uuid ||= read_attribute(:uuid).unpack("C*").map {|n| sprintf("%02x", n)}.join
  end
end

Конечно, вам нужен столбец BINARY, потому что вы отправляете необработанные байты в базу данных.Миграция, такая как эта:

class AddUuidToUsers
  def self.up
    execute "ALTER TABLE users ADD uuid BINARY(16)"
  end
end
1 голос
/ 08 февраля 2010

Я посмотрел исходный код ActiveRecord 2.3.5 (mysql_adapter.rb). Просмотр хэша NATIVE_DATABASE_TYPES показывает, что он не поддерживает тип данных BINARY (16):

NATIVE_DATABASE_TYPES = {
  :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY".freeze,
  :string      => { :name => "varchar", :limit => 255 },
  :text        => { :name => "text" },
  :integer     => { :name => "int", :limit => 4 },
  :float       => { :name => "float" },
  :decimal     => { :name => "decimal" },
  :datetime    => { :name => "datetime" },
  :timestamp   => { :name => "datetime" },
  :time        => { :name => "time" },
  :date        => { :name => "date" },
  :binary      => { :name => "blob" },
  :boolean     => { :name => "tinyint", :limit => 1 }
}

Также обратите внимание: двоичный файл - это не то, что вам нужно, потому что он создает столбец BLOB.

Если у вас есть склонность, я бы рекомендовал расширить ActiveRecord для поддержки типа BINARY (16).

Обновление: после некоторых поисков следующий пост в блоге Мэтью Хиггинса кажется многообещающим («Хотя произвольные операторы SQL могут выполняться при переносе, альтернативой является расширение адаптера MySql для поддержки новых типов столбцов».): http://www.strictlyuntyped.com/2008/07/mysql-lovin-part-2-adding-new-column.html

Если вы заставите это работать, я надеюсь, что вы поделитесь своими мыслями. Как и Мэтью, я бы хотел, чтобы у ActiveRecord был более чистый API для добавления типов столбцов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...