Пользовательская сериализация для полей в Rails
есть ли способ иметь пользовательскую сериализацию для полей в rails, метод, который запускается, когда поле сохраняется и загружается для преобразования из/в строку, которая в конечном итоге сохраняется в базе данных.
в частности, то, что я хочу сделать, это иметь поле символа типа gender, с возможными значениями :male и :female, хранящими "male" и "female" в базе данных. Есть некоторые обходные пути, как:
def gender
  read_attribute(:gender).try(:to_sym)
end
но остается obj.атрибуты неизменны, поэтому это дырявые абстракции.
7 ответов
вы можете сделать это в Rails 3.1. Объект, который вы хотите сериализовать должен ответить load и dump методы.
вот пример сериализации строки в base64.
class User < ActiveRecord::Base
  class Base64
    def load(text)
      return unless text
      text.unpack('m').first
    end
    def dump(text)
      [text].pack 'm'
    end
  end
  serialize :bank_account_number, Base64.new
end
Подробнее см.: http://archives.edgerails.info/articles/what-s-new-in-edge-rails/2011/03/09/custom-activerecord-attribute-serialization/index.html
def whachamacallit
  read_attribute("whachamacallit").to_sym
end
def whachamacallit=(name)
  write_attribute("whachamacallit", name.to_s)
end
храните их как жала в базе данных, но извлекайте их как символы, когда вы вытаскиваете их, а затем конвертируйте обратно перед сохранением. будет работать с любым числом или комбинацией строк / символов.
ограничить лишь немногие
validates_inclusion_of :whachamacallit, :in => [ :male, :female, :unknown, :hidden ]
от http://blog.quov.is/2012/05/01/custom-activerecord-attribute-serializers/
class Recipe < ActiveRecord::Base
  serialize :ingredients, IngredientsList
end
class IngredientsList < Array
  def self.dump(ingredients)
    ingredients ? ingredients.join("\n") : nil
  end
  def self.load(ingredients)
    ingredients ? new(ingredients.split("\n")) : nil
  end
end
вы можете определить модели to_xml для модели, и это сделает это http://api.rubyonrails.org/classes/ActiveRecord/Serialization.html
можно определить Маршалла.свалка и положить таким образом, я думаю, но его что-то смотреть в
можно использовать serialize метод внутри модели. Пожалуйста, ссылку на эту ссылку:
http://api.rubyonrails.org/classes/ActiveRecord/Base.html
(ПС. поиск по ключевому слову "serialize" на этой странице ;D)
короче говоря, вы можете сделать это:
class YourModel < ActiveRecord::Base
  serialize :db_field
end
Rails автоматически сериализует поле перед сохранением в базе данных и десериализует его после извлечения из базы данных.
ну, только для мужчин / женщин вы можете просто сделать логический столбец, как мужчина, и если это было ложно, предположим, что это означает женщину, добавьте методы обертки для него
def female? 
  return !self.male?
end
мы только что выпустили драгоценный камень (AttributeHelpers), который делает именно это. Отказ от ответственности: я сопровождающий для драгоценного камня.
Это позволяет назвать attr_symbol :gender в определении класса и сериализация происходит автоматически.
