Paper Trail Gem: как использовать пользовательский тип item_type для конкретной модели

Есть ли возможность настроить item_type для версии? У меня есть класс Post, и item_type по умолчанию для него будет Post; есть ли возможность настроить это Foo?

ОБНОВЛЕНИЕ с примером:

class Post < ActiveRecord::Base
  has_paper_trail
end

post = Post.create # this creates a new post along with a version.
version = post.versions.first
version.item_type = 'Post' # Item type here is the name of the base model 'Post'.

person Hai Nguyen    schedule 12.05.2016    source источник
comment
Обновил заголовок и пост. Это для жемчужины бумажного следа.   -  person Hai Nguyen    schedule 12.05.2016


Ответы (3)


Есть ли возможность настроить item_type для версии? У меня есть класс Post, и item_type по умолчанию для него будет Post; есть ли возможность настроить это как Foo?

Нет. Когда вы вызываете has_paper_trail, добавляется полиморфная ассоциация с именем item. Таким образом, PaperTrail не контролирует столбец базы данных item_type, а ActiveRecord.

Вот определение ассоциации has_many:

has_many(
  versions_association_name, # Usually "versions"
  -> { order(model.timestamp_sort_order) }, # Usually "created_at"
  class_name: version_class_name, # Usually "PaperTrail::Version"
  as: :item # Specifies a polymorphic interface
)
person Jared Beck    schedule 06.06.2016

Просто наткнулся на это, понял, что это немного устарело, но подумал, что поделюсь своим решением, поскольку у меня было такое же требование. Это только частичное решение, но оно работает

Я расширил класс PaperTrail Version и переопределил геттер item_type.

class AuditTrail < PaperTrail::Version
xss_foliate :except => [:object, :object_changes]

    def item_type
        if(self[:item_type] == "SomethingIWantToChange")
            return "Different String"
        end

        return self[:item_type]
    end
end

Затем я настроил каждую из своих моделей на использование этого класса следующим образом:

has_paper_trail :class_name => 'AuditTrail'

Затем я могу запросить таблицу версий, и возвращенные объекты будут проходить через переопределенный геттер, а item_type будет таким, как мне нужно:

audit_records = AuditTrail.where(someproperty: "something")

Так что это на самом деле не изменяет его в БД, когда он написан, но это лучший способ, который я мог найти, чтобы представить его по-другому для моего интерфейса.

Обратите внимание, что он не изменяет item_type, если вы извлекаете версии без использования запроса из вашего расширенного объекта, т.е.:

Someobject.find(1).versions.last

^ это по-прежнему возвращает item_type из БД

person Andy    schedule 23.01.2017

Вам нужен вариант class_name. Это должно работать с вашим примером:

class Post < ActiveRecord::Base
  has_paper_trail :class_name => 'Foo'
end

Это приведет к версии класса Post как Foo.

Дополнительную информацию можно найти в документации Paper Trail на Классы пользовательских версий.

person Michael Gaskill    schedule 12.05.2016
comment
@HaiNguyen Это ответило на ваш вопрос? Если да, нажмите на галочку рядом с ответом, чтобы принять его. Галочка станет зеленой. Плюсы тоже всегда приветствуются! - person Michael Gaskill; 22.05.2016
comment
Вопрос ОП касался столбца базы данных versions.item_type. Передача :class_name в has_paper_trail не должна повлиять на этот столбец базы данных. - person Jared Beck; 06.06.2016