#ruby-on-rails #ruby #paper-trail-gem #trix
#ruby-on-rails #ruby #бумажный след-драгоценный камень #trix
Вопрос:
У меня был Paper Trail Gem, прекрасно настроенный в моей статье basic model, в которой был text
столбец с именем body
. Однако после того, как я внедрил текст действия в свое приложение и удалил столбец body
из модели статьи, я не могу получить Paper Trail для отслеживания изменений в соответствующем body
столбце. Как я могу заставить это работать?
Отказ от ответственности: я новичок в Rails.
Article.rb
...
has_rich_text :body
has_paper_trail
...
Схема статей (после удаления: основной столбец)
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
Я бы хотел вернуть приложению ту же функциональность, что и раньше, где я мог видеть изменения, внесенные в текст статьи. Например. кто-то добавил предложение, удалил слово и т.д..
Комментарии:
1. доступна ли
ActionTextRichText
модель? если да, может быть, вы можете добавитьhas_paper_trail
к нему2. @mr_sudaca Модель недоступна.
Ответ №1:
Объединение ответов сработало для меня:
# 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'
Комментарии:
1. Где именно это потребуется?
2. Мне это требовалось в модели, в которой смонтирован action_text
has_rich_text
, но это также может потребоваться в application_controller.rb или что-то более глобальное, я думаю. Возможно, вы могли бы также поместить этот код в файл инициализатора вconfig/initializers/
Ответ №2:
Попробуйте добавить config/initializers/rich_text_paper_trail.rb
файл с:
ActiveSupport.on_load(:action_text_rich_text) do
has_paper_trail
end
Комментарии:
1. Не сработало. Новые версии (обновления или создания) не сохраняются в
versions
таблице.
Ответ №3:
Попробовав все представленные здесь варианты, у меня появилась идея для этого обходного пути, который в конце концов сработал действительно хорошо.
Что я сделал, так это то, что я просто заменил текст действия на чистую версию Trix Editor, и поэтому я смог сохранить :body
свою модель article.rb, сохранить версии всего объекта и показать различия. Ура! 🎉
Комментарии:
1. Как вы обходили часть вложений ActiveStorage?
Ответ №4:
Ruby позволяет вам (к лучшему или к худшему) вносить изменения в вещи на лету.
Поместите это в инициализатор:
ActionText::RichText.class_eval do
has_paper_trail
end
Комментарии:
1. Я пытался, но теперь я даже не могу запустить
rails server
, потому что я бы получил:...gems/activerecord-5.2.2/lib/active_record/dynamic_matchers.rb:22:in `method_missing': undefined method `has_many_attached' for #<Class:0x00007fa19c03afd0> (NoMethodError)
2. попробуйте создать и поместить его в
app/models/action_text/rich_text.rb
3. Я бы получил:
Circular dependency detected while autoloading constant ActionText::RichText
4. Вы могли бы попробовать поместить это в инициализатор и обернуть в
ActiveSupport.on_load(:active_storage_blob) do ... end
Ответ №5:
Мы сделали нечто подобное в Rails 5.2, используя архивную версию active text.
Gemfile
gem 'actiontext', git: 'https://github.com/kobaltz/actiontext.git', branch: 'archive', require: 'action_text'
модели/article.rb
class Article < ApplicationRecord
has_paper_tail
serialize :body, ActionText::Content
...
end
помощники/trix_editor_helper.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
valueamp;.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
Затем мы установили trix версии 1.1 с cdn и использовали стандартный trix-attachments.js и прямые загрузки.
Хотите перейти на Rails 6 и сохранить эту концепцию, если это возможно.