Пользовательская сериализация для полей в Rails - PullRequest
9 голосов
/ 17 декабря 2010

Есть ли способ иметь настраиваемую сериализацию для полей в рельсах, метод, который запускается, когда поле сохраняется и загружается для преобразования из / в строку, которая в конечном итоге сохраняется в базе данных.

В частности, я хочу иметь поле с символом типа, например, пол, с возможными значениями: мужской и женский, сохраняя «мужской» и «женский» в базе данных.Есть несколько обходных путей, например:

def gender
  read_attribute(:gender).try(:to_sym)
end

, но это оставляет атрибуты obj.attributes неизменными, поэтому это утечка абстракции.

Ответы [ 7 ]

10 голосов
/ 24 апреля 2011

Вы можете сделать это в 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

4 голосов
/ 22 декабря 2010
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 ]
2 голосов
/ 02 августа 2012

С 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
0 голосов
/ 15 января 2015

Мы только что выпустили гем ( AttributeHelpers ), который делает именно это.Отказ от ответственности: я поддерживаю самоцвет.

Он позволяет вам вызывать attr_symbol :gender в вашем определении класса, и сериализация происходит автоматически.

0 голосов
/ 20 декабря 2010

хорошо для мужчин и женщин, вы можете просто сделать булеву колонку, как у мужчины, и, если она ложна, предположить, что это значит женщина, добавить для нее методы-оболочки

def female? 
  return !self.male?
end
0 голосов
/ 17 декабря 2010

Вы можете использовать serialize метод внутри модели. Пожалуйста, ссылку на эту ссылку: http://api.rubyonrails.org/classes/ActiveRecord/Base.html (пс. поисковое ключевое слово "serialize" на этой странице; D)

Короче говоря, вы могли бы сделать это:

class YourModel < ActiveRecord::Base
  serialize :db_field
end

Rails автоматически сериализует поле перед сохранением в базу данных и десериализует его после извлечения из базы данных.

0 голосов
/ 17 декабря 2010

вы можете определить модели to_xml для модели, и она сделает это http://api.rubyonrails.org/classes/ActiveRecord/Serialization.html

я могу определить Marshall.dump и поместить его таким образом, я думаю, но это что-то, что нужно рассмотреть

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