Приведение к пользовательскому типу массива PostgreSQL - PullRequest
0 голосов
/ 09 октября 2018

В приложении Rails (5.2) у меня есть модель Project с атрибутом tags, определенным как массив Postgresql.

  create_table :projects do |t|
    ...
    t.text :tags, array: true, default: []
    ...
  end

Вместо обработки тегов как строк, которые я хотел бы привестиих к Tag s объектам

class Tag
  ...
  attr_reader :name

  def initialize(name)
    @name = name
  end
  ...
end

Для достижения этого я пытаюсь использовать API атрибутов, который поставляется с Rails 5.

class Project < ApplicationRecord
  attribute :tags, TagType.new, array: true
  ...
end

class TagType < ActiveRecord::Type::Value
  def cast(names)
    names.split(',').map { |name| Tag.new(name) }
  end
end

Такого рода работа создаетTag s объект, но у первого и последнего есть квадратные скобки в имени.

Project.create(tags: ['one', 'two', 'three'])
Project.first.tags.map(&:name) #=> ['{one', 'two', 'three}']

Есть ли лучший способ, чем вручную удалять скобки из names в TagType, чтобы получить правильные Tag s?

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

1 Ответ

0 голосов
/ 11 октября 2018

Здесь код, который я получил в итоге

class TagType < ActiveRecord::Type::Value
  include ActiveModel::Type::Helpers::Mutable

  def cast(name)
    Tag.new(name)
  end

  def deserialize(names)
    PG::TextDecoder::Array.new.decode(names).map { |name| cast(name) }
  end

  def serialize(tags)
    PG::TextEncoder::Array.new.encode(tags.map(&:name))
  end
end

Надеюсь, это поможет.

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