ruby 如何让Paper_trail与Action Text一起工作?

9wbgstp7  于 12个月前  发布在  Ruby
关注(0)|答案(6)|浏览(121)

我用我的基本模型文章很好地设置了Paper Trail Gem,其中有一个名为bodytext列。但是,在我将Action Text实现到我的应用程序中并从Article模型中删除列body之后,**我无法让Paper Trail跟踪关联的body列中的更改。**我如何才能让它工作?
免责声明:我是Rails的新手。
Article.rb

...
  has_rich_text :body
  has_paper_trail
...

Articles Schema(删除后:body列)

create_table "articles", force: :cascade do |t|
    t.string "title"
    t.string "slug"
    t.datetime "archived_at"
    t.datetime "published_at"
    ...
  end

操作文本架构

create_table "action_text_rich_texts", force: :cascade do |t|
    t.string "name", null: false
    t.text "body"
    t.string "record_type", null: false
    t.bigint "record_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
  end

我想返回相同的功能,以应用程序之前,我能够看到的变化,在身体的文章。例如,某人添加了一个句子,删除了一个单词等。

zd287kbt

zd287kbt1#

把这些答案结合起来对我来说很有效:

# frozen_string_literal: true

ActiveSupport.on_load(:action_text_rich_text) do
  ActionText::RichText.class_eval do
    has_paper_trail
  end
end

lib/rich_text_paper_trail.rb和确保这个文件被加载!例如,明确要求:require 'rich_text_paper_trail'

tyu7yeag

tyu7yeag2#

尝试使用以下命令添加config/initializers/rich_text_paper_trail.rb文件:

ActiveSupport.on_load(:action_text_rich_text) do
  has_paper_trail
end
qacovj5a

qacovj5a3#

在尝试了这里提供的所有选项后,我想到了一个解决方案,最终效果非常好。
我所做的是我只是用纯Trix Editor版本替换Action Text,因此我能够在我的article.rb模型中保留:body,保存整个对象的版本并显示差异。好耶!🎉

2w3kk1z5

2w3kk1z54#

Ruby允许您(无论好坏)动态地对事物进行修改。
把它放在一个初始化器中:

ActionText::RichText.class_eval do 
  has_paper_trail
end
6g8kf2rb

6g8kf2rb5#

我们已经在Rails 5.2上使用活动文本的归档版本做了类似的事情。
Gemfile

gem 'actiontext', git: 'https://github.com/kobaltz/actiontext.git', branch: 'archive', require: 'action_text'

models/article.rb

class Article < ApplicationRecord
  has_paper_tail
  serialize :body, ActionText::Content
  ...
end

helpers/编辑器助手.rb

require 'action_view/helpers/tags/placeholderable'

module TrixEditorHelper
  mattr_accessor(:id, instance_accessor: false) { 0 }

# Returns a +trix-editor+ tag that instantiates the Trix JavaScript editor as well as a hidden field
# that Trix will write to on changes, so the content will be sent on form submissions.
#
# ==== Options
# * <tt>:class</tt> - Defaults to "trix-content" which ensures default styling is applied.
#
# ==== Example
#
#   rich_text_area_tag "content", message.content
#   # <input type="hidden" name="content" id="trix_input_post_1">
#   # <trix-editor id="content" input="trix_input_post_1" class="trix-content" ...></trix-editor>

  def trix_editor_tag(name, value = nil, options = {})
    options = options.symbolize_keys

    options[:input] ||= "trix_input_#{TrixEditorHelper.id += 1}"
    options[:class] ||= "trix-content"

    options[:data] ||= {}
    options[:data][:direct_upload_url] = main_app.rails_direct_uploads_url
    options[:data][:blob_url_template] = main_app.rails_service_blob_url(":signed_id", ":filename")

    editor_tag = content_tag("trix-editor", "", options)
    input_tag = hidden_field_tag(name, value, id: options[:input])

    input_tag + editor_tag
  end
end

module ActionView::Helpers
  class Tags::TrixEditor < Tags::Base
    include Tags::Placeholderable
    delegate :dom_id, to: ActionView::RecordIdentifier

    def render
      options = @options.stringify_keys
      add_default_name_and_id(options)
      options['input'] ||= dom_id(object, [options['id'], :trix_input].compact.join('_')) if object
      @template_object.trix_editor_tag(options.delete("name"), editable_value, options)
    end

    def editable_value
      value&.try(:to_trix_html)
    end
  end

  module FormHelper
    def trix_editor(object_name, method, options = {})
      Tags::TrixEditor.new(object_name, method, self, options).render
    end
  end

  class FormBuilder
    def trix_editor(method, options = {})
      @template.trix_editor(@object_name, method, objectify_options(options))
    end
  end
end

然后,我们从cdn安装了xml1.1版,并使用了标准的trix-attachments.js和Direct xmlads。
希望升级到Rails 6,如果可能的话,保持这个概念。

vof42yt1

vof42yt16#

我受到这个solution的启发,只是将其更改为使用PaperTrail::Version来存储更改。

# config/initializers/action_text_version.rb

ActiveSupport.on_load(:action_text_rich_text) do
  ActionText::RichText.class_eval do
    before_save :record_change

    private

    def record_change
      return unless body_changed?
      return unless PaperTrail.request.enabled_for_model?(record.class)

      PaperTrail::Version.create(item: record, event: "update", whodunnit: PaperTrail::Request.whodunnit, object_changes: {name => [body.to_s, body_was.to_s]})
     end
  end  
end

相关问题