Allow Attachables to override default template when attachment is missing
This commit is contained in:
parent
c88ca3b720
commit
fbf0145f19
@ -1,3 +1,12 @@
|
||||
* Attachables now can override default attachment missing template.
|
||||
|
||||
When rendering ActionText attachments where the underlying attachable model has
|
||||
been removed, a fallback template is used. You now can override this template on
|
||||
a per-model basis. For example, you could render a placeholder image for a file
|
||||
attachment or the text "Deleted User" for a User attachment.
|
||||
|
||||
*Matt Swanson*, *Joel Drapper*
|
||||
|
||||
* Update bundled Trix version from `1.3.1` to `2.0.4`.
|
||||
|
||||
*Sean Doyle*
|
||||
|
@ -15,7 +15,7 @@ def from_node(node)
|
||||
elsif attachable = ActionText::Attachables::RemoteImage.from_node(node)
|
||||
attachable
|
||||
else
|
||||
ActionText::Attachables::MissingAttachable
|
||||
ActionText::Attachables::MissingAttachable.new(node["sgid"])
|
||||
end
|
||||
end
|
||||
|
||||
@ -37,6 +37,10 @@ def attachable_from_sgid(sgid)
|
||||
def from_attachable_sgid(sgid)
|
||||
ActionText::Attachable.from_attachable_sgid(sgid, only: self)
|
||||
end
|
||||
|
||||
def to_missing_attachable_partial_path
|
||||
ActionText::Attachables::MissingAttachable::DEFAULT_PARTIAL_PATH
|
||||
end
|
||||
end
|
||||
|
||||
def attachable_sgid
|
||||
|
@ -2,11 +2,25 @@
|
||||
|
||||
module ActionText
|
||||
module Attachables
|
||||
module MissingAttachable
|
||||
class MissingAttachable
|
||||
extend ActiveModel::Naming
|
||||
|
||||
def self.to_partial_path
|
||||
"action_text/attachables/missing_attachable"
|
||||
DEFAULT_PARTIAL_PATH = "action_text/attachables/missing_attachable"
|
||||
|
||||
def initialize(sgid)
|
||||
@sgid = SignedGlobalID.parse(sgid, for: ActionText::Attachable::LOCATOR_NAME)
|
||||
end
|
||||
|
||||
def to_partial_path
|
||||
if model
|
||||
model.to_missing_attachable_partial_path
|
||||
else
|
||||
DEFAULT_PARTIAL_PATH
|
||||
end
|
||||
end
|
||||
|
||||
def model
|
||||
@sgid&.model_name.to_s.safe_constantize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,6 +1,10 @@
|
||||
class Person < ApplicationRecord
|
||||
include ActionText::Attachable
|
||||
|
||||
def self.to_missing_attachable_partial_path
|
||||
"people/missing_attachable"
|
||||
end
|
||||
|
||||
def to_trix_content_attachment_partial_path
|
||||
"people/trix_content_attachment"
|
||||
end
|
||||
|
@ -0,0 +1 @@
|
||||
<span class="missing-attachable">Missing person</span>
|
@ -48,4 +48,13 @@ class ActionText::ControllerRenderTest < ActionDispatch::IntegrationTest
|
||||
|
||||
assert_select ".mentioned-person", text: alice.name
|
||||
end
|
||||
|
||||
test "resolves missing ActionText::Attachable based on their to_missing_attachable_partial_path" do
|
||||
alice = people(:alice)
|
||||
alice.destroy!
|
||||
|
||||
get messages_path
|
||||
|
||||
assert_select ".missing-attachable", text: "Missing person"
|
||||
end
|
||||
end
|
||||
|
@ -56,19 +56,26 @@ class ActionText::ContentTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "identifies destroyed attachables as missing" do
|
||||
attachable = create_file_blob(filename: "racecar.jpg", content_type: "image/jpeg")
|
||||
html = %Q(<action-text-attachment sgid="#{attachable.attachable_sgid}"></action-text-attachment>)
|
||||
attachable.destroy!
|
||||
file = create_file_blob(filename: "racecar.jpg", content_type: "image/jpeg")
|
||||
html = %Q(<action-text-attachment sgid="#{file.attachable_sgid}"></action-text-attachment>)
|
||||
file.destroy!
|
||||
content = content_from_html(html)
|
||||
assert_equal 1, content.attachments.size
|
||||
assert_equal ActionText::Attachables::MissingAttachable, content.attachments.first.attachable
|
||||
|
||||
attachable = content.attachments.first.attachable
|
||||
assert_kind_of ActionText::Attachables::MissingAttachable, attachable
|
||||
assert_equal file.class, attachable.model
|
||||
assert_equal ActionText::Attachables::MissingAttachable::DEFAULT_PARTIAL_PATH, attachable.to_partial_path
|
||||
end
|
||||
|
||||
test "extracts missing attachables" do
|
||||
html = '<action-text-attachment sgid="missing"></action-text-attachment>'
|
||||
content = content_from_html(html)
|
||||
assert_equal 1, content.attachments.size
|
||||
assert_equal ActionText::Attachables::MissingAttachable, content.attachments.first.attachable
|
||||
|
||||
attachable = content.attachments.first.attachable
|
||||
assert_kind_of ActionText::Attachables::MissingAttachable, attachable
|
||||
assert_nil attachable.model
|
||||
end
|
||||
|
||||
test "converts Trix-formatted attachments" do
|
||||
|
@ -205,12 +205,38 @@ partial-local variable:
|
||||
<span><%= image_tag user.avatar %> <%= user.name %></span>
|
||||
```
|
||||
|
||||
If Action Text is unable to resolve the `User` instance (for example, if the
|
||||
record has been deleted), then a default fallback partial will be rendered.
|
||||
|
||||
Rails provides a global partial for missing attachments. This partial is installed
|
||||
in your application at `views/action_text/attachables/missing_attachable` and can
|
||||
be modified if you want to render different HTML.
|
||||
|
||||
To render a different missing attachment partial, define a class-level
|
||||
`to_missing_attachable_partial_path` method:
|
||||
|
||||
```ruby
|
||||
class User < ApplicationRecord
|
||||
def self.to_missing_attachable_partial_path
|
||||
"users/missing_attachable"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Then declare that partial.
|
||||
|
||||
```html+erb
|
||||
<%# app/views/users/missing_attachable.html.erb %>
|
||||
<span>Deleted user</span>
|
||||
```
|
||||
|
||||
To integrate with Action Text `<action-text-attachment>` element rendering, a
|
||||
class must:
|
||||
|
||||
* include the `ActionText::Attachable` module
|
||||
* implement `#to_sgid(**options)` (made available through the [`GlobalID::Identification` concern][global-id])
|
||||
* (optional) declare `#to_attachable_partial_path`
|
||||
* (optional) declare a class-level method `#to_missing_attachable_partial_path` for handling missing records
|
||||
|
||||
By default, all `ActiveRecord::Base` descendants mix-in
|
||||
[`GlobalID::Identification` concern][global-id], and are therefore
|
||||
|
Loading…
Reference in New Issue
Block a user