Пользовательская сериализация для полей в 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 в определении класса и сериализация происходит автоматически.