actiontext 7.1.5.1 → 7.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actiontext might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -136
- data/app/assets/javascripts/actiontext.esm.js +3 -3
- data/app/assets/javascripts/actiontext.js +3 -3
- data/app/assets/javascripts/trix.js +203 -1758
- data/app/helpers/action_text/content_helper.rb +2 -9
- data/app/helpers/action_text/tag_helper.rb +38 -28
- data/app/models/action_text/encrypted_rich_text.rb +2 -2
- data/app/models/action_text/record.rb +2 -0
- data/app/models/action_text/rich_text.rb +58 -26
- data/db/migrate/20180528164100_create_action_text_tables.rb +1 -1
- data/lib/action_text/attachable.rb +35 -33
- data/lib/action_text/attachables/content_attachment.rb +2 -0
- data/lib/action_text/attachables/missing_attachable.rb +2 -0
- data/lib/action_text/attachables/remote_image.rb +2 -0
- data/lib/action_text/attachment.rb +27 -25
- data/lib/action_text/attachment_gallery.rb +2 -0
- data/lib/action_text/attachments/caching.rb +2 -0
- data/lib/action_text/attachments/minification.rb +2 -0
- data/lib/action_text/attachments/trix_conversion.rb +2 -0
- data/lib/action_text/attribute.rb +36 -22
- data/lib/action_text/content.rb +47 -31
- data/lib/action_text/deprecator.rb +2 -0
- data/lib/action_text/encryption.rb +2 -0
- data/lib/action_text/engine.rb +2 -0
- data/lib/action_text/fixture_set.rb +34 -34
- data/lib/action_text/fragment.rb +4 -0
- data/lib/action_text/gem_version.rb +6 -4
- data/lib/action_text/html_conversion.rb +2 -0
- data/lib/action_text/plain_text_conversion.rb +3 -6
- data/lib/action_text/rendering.rb +2 -0
- data/lib/action_text/serialization.rb +2 -0
- data/lib/action_text/system_test_helper.rb +20 -17
- data/lib/action_text/trix_attachment.rb +2 -0
- data/lib/action_text/version.rb +3 -1
- data/lib/generators/action_text/install/install_generator.rb +10 -3
- data/lib/rails/generators/test_unit/install_generator.rb +2 -0
- data/package.json +1 -1
- metadata +18 -18
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "rails-html-sanitizer"
|
4
6
|
|
5
7
|
module ActionText
|
@@ -14,15 +16,6 @@ module ActionText
|
|
14
16
|
sanitize_action_text_content(render_action_text_attachments(content))
|
15
17
|
end
|
16
18
|
|
17
|
-
def sanitize_content_attachment(content_attachment)
|
18
|
-
sanitizer.sanitize(
|
19
|
-
content_attachment,
|
20
|
-
tags: sanitizer_allowed_tags,
|
21
|
-
attributes: sanitizer_allowed_attributes,
|
22
|
-
scrubber: scrubber,
|
23
|
-
)
|
24
|
-
end
|
25
|
-
|
26
19
|
def sanitize_action_text_content(content)
|
27
20
|
sanitizer.sanitize(
|
28
21
|
content.to_html,
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/object/try"
|
4
6
|
require "action_view/helpers/tags/placeholderable"
|
5
7
|
|
@@ -7,20 +9,24 @@ module ActionText
|
|
7
9
|
module TagHelper
|
8
10
|
cattr_accessor(:id, instance_accessor: false) { 0 }
|
9
11
|
|
10
|
-
# Returns a
|
11
|
-
# that Trix will write to on changes, so the content will
|
12
|
+
# Returns a `trix-editor` tag that instantiates the Trix JavaScript editor as
|
13
|
+
# well as a hidden field that Trix will write to on changes, so the content will
|
14
|
+
# be sent on form submissions.
|
15
|
+
#
|
16
|
+
# #### Options
|
17
|
+
# * `:class` - Defaults to "trix-content" so that default styles will be
|
18
|
+
# applied. Setting this to a different value will prevent default styles
|
19
|
+
# from being applied.
|
20
|
+
# * `[:data][:direct_upload_url]` - Defaults to `rails_direct_uploads_url`.
|
21
|
+
# * `[:data][:blob_url_template]` - Defaults to
|
22
|
+
# `rails_service_blob_url(":signed_id", ":filename")`.
|
12
23
|
#
|
13
|
-
# ==== Options
|
14
|
-
# * <tt>:class</tt> - Defaults to "trix-content" so that default styles will be applied.
|
15
|
-
# Setting this to a different value will prevent default styles from being applied.
|
16
|
-
# * <tt>[:data][:direct_upload_url]</tt> - Defaults to +rails_direct_uploads_url+.
|
17
|
-
# * <tt>[:data][:blob_url_template]</tt> - Defaults to <tt>rails_service_blob_url(":signed_id", ":filename")</tt>.
|
18
24
|
#
|
19
|
-
#
|
25
|
+
# #### Example
|
20
26
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
27
|
+
# rich_text_area_tag "content", message.content
|
28
|
+
# # <input type="hidden" name="content" id="trix_input_post_1">
|
29
|
+
# # <trix-editor id="content" input="trix_input_post_1" class="trix-content" ...></trix-editor>
|
24
30
|
def rich_text_area_tag(name, value = nil, options = {})
|
25
31
|
options = options.symbolize_keys
|
26
32
|
form = options.delete(:form)
|
@@ -56,23 +62,27 @@ module ActionView::Helpers
|
|
56
62
|
end
|
57
63
|
|
58
64
|
module FormHelper
|
59
|
-
# Returns a
|
60
|
-
# that Trix will write to on changes, so the content will
|
65
|
+
# Returns a `trix-editor` tag that instantiates the Trix JavaScript editor as
|
66
|
+
# well as a hidden field that Trix will write to on changes, so the content will
|
67
|
+
# be sent on form submissions.
|
68
|
+
#
|
69
|
+
# #### Options
|
70
|
+
# * `:class` - Defaults to "trix-content" which ensures default styling is
|
71
|
+
# applied.
|
72
|
+
# * `:value` - Adds a default value to the HTML input tag.
|
73
|
+
# * `[:data][:direct_upload_url]` - Defaults to `rails_direct_uploads_url`.
|
74
|
+
# * `[:data][:blob_url_template]` - Defaults to
|
75
|
+
# `rails_service_blob_url(":signed_id", ":filename")`.
|
61
76
|
#
|
62
|
-
# ==== Options
|
63
|
-
# * <tt>:class</tt> - Defaults to "trix-content" which ensures default styling is applied.
|
64
|
-
# * <tt>:value</tt> - Adds a default value to the HTML input tag.
|
65
|
-
# * <tt>[:data][:direct_upload_url]</tt> - Defaults to +rails_direct_uploads_url+.
|
66
|
-
# * <tt>[:data][:blob_url_template]</tt> - Defaults to <tt>rails_service_blob_url(":signed_id", ":filename")</tt>.
|
67
77
|
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
78
|
+
# #### Example
|
79
|
+
# rich_text_area :message, :content
|
80
|
+
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1">
|
81
|
+
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
72
82
|
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
83
|
+
# rich_text_area :message, :content, value: "<h1>Default message</h1>"
|
84
|
+
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>">
|
85
|
+
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
76
86
|
def rich_text_area(object_name, method, options = {})
|
77
87
|
Tags::ActionText.new(object_name, method, self, options).render
|
78
88
|
end
|
@@ -81,9 +91,9 @@ module ActionView::Helpers
|
|
81
91
|
class FormBuilder
|
82
92
|
# Wraps ActionView::Helpers::FormHelper#rich_text_area for form builders:
|
83
93
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
94
|
+
# <%= form_with model: @message do |f| %>
|
95
|
+
# <%= f.rich_text_area :content %>
|
96
|
+
# <% end %>
|
87
97
|
#
|
88
98
|
# Please refer to the documentation of the base helper for details.
|
89
99
|
def rich_text_area(method, options = {})
|
@@ -1,55 +1,87 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionText
|
4
|
-
#
|
6
|
+
# # Action Text RichText
|
5
7
|
#
|
6
|
-
# The RichText record holds the content produced by the Trix editor in a
|
7
|
-
# It also holds all the references to the embedded
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# The RichText record holds the content produced by the Trix editor in a
|
9
|
+
# serialized `body` attribute. It also holds all the references to the embedded
|
10
|
+
# files, which are stored using Active Storage. This record is then associated
|
11
|
+
# with the Active Record model the application desires to have rich text content
|
12
|
+
# using the `has_rich_text` class method.
|
10
13
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
+
# class Message < ActiveRecord::Base
|
15
|
+
# has_rich_text :content
|
16
|
+
# end
|
14
17
|
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
18
|
+
# message = Message.create!(content: "<h1>Funny times!</h1>")
|
19
|
+
# message.content #=> #<ActionText::RichText....
|
20
|
+
# message.content.to_s # => "<h1>Funny times!</h1>"
|
21
|
+
# message.content.to_plain_text # => "Funny times!"
|
19
22
|
#
|
23
|
+
# message = Message.create!(content: "<div onclick='action()'>safe<script>unsafe</script></div>")
|
24
|
+
# message.content #=> #<ActionText::RichText....
|
25
|
+
# message.content.to_s # => "<div>safeunsafe</div>"
|
26
|
+
# message.content.to_plain_text # => "safeunsafe"
|
20
27
|
class RichText < Record
|
21
|
-
|
28
|
+
##
|
29
|
+
# :method: to_s
|
30
|
+
#
|
31
|
+
# Safely transforms RichText into an HTML String.
|
32
|
+
#
|
33
|
+
# message = Message.create!(content: "<h1>Funny times!</h1>")
|
34
|
+
# message.content.to_s # => "<h1>Funny times!</h1>"
|
35
|
+
#
|
36
|
+
# message = Message.create!(content: "<div onclick='action()'>safe<script>unsafe</script></div>")
|
37
|
+
# message.content.to_s # => "<div>safeunsafe</div>"
|
22
38
|
|
23
39
|
serialize :body, coder: ActionText::Content
|
24
40
|
delegate :to_s, :nil?, to: :body
|
25
41
|
|
42
|
+
##
|
43
|
+
# :method: record
|
44
|
+
#
|
45
|
+
# Returns the associated record.
|
26
46
|
belongs_to :record, polymorphic: true, touch: true
|
47
|
+
|
48
|
+
##
|
49
|
+
# :method: embeds
|
50
|
+
#
|
51
|
+
# Returns the `ActiveStorage::Blob`s of the embedded files.
|
27
52
|
has_many_attached :embeds
|
28
53
|
|
29
54
|
before_save do
|
30
55
|
self.embeds = body.attachables.grep(ActiveStorage::Blob).uniq if body.present?
|
31
56
|
end
|
32
57
|
|
33
|
-
# Returns
|
58
|
+
# Returns a plain-text version of the markup contained by the `body` attribute,
|
59
|
+
# with tags removed but HTML entities encoded.
|
60
|
+
#
|
61
|
+
# message = Message.create!(content: "<h1>Funny times!</h1>")
|
62
|
+
# message.content.to_plain_text # => "Funny times!"
|
63
|
+
#
|
64
|
+
# NOTE: that the returned string is not HTML safe and should not be rendered in
|
65
|
+
# browsers.
|
34
66
|
#
|
35
|
-
#
|
36
|
-
#
|
67
|
+
# message = Message.create!(content: "<script>alert()</script>")
|
68
|
+
# message.content.to_plain_text # => "<script>alert()</script>"
|
37
69
|
def to_plain_text
|
38
70
|
body&.to_plain_text.to_s
|
39
71
|
end
|
40
72
|
|
41
|
-
# Returns the
|
73
|
+
# Returns the `body` attribute in a format that makes it editable in the Trix
|
42
74
|
# editor. Previews of attachments are rendered inline.
|
43
75
|
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
76
|
+
# content = "<h1>Funny Times!</h1><figure data-trix-attachment='{\"sgid\":\"..."\}'></figure>"
|
77
|
+
# message = Message.create!(content: content)
|
78
|
+
# message.content.to_trix_html # =>
|
79
|
+
# # <div class="trix-content">
|
80
|
+
# # <h1>Funny times!</h1>
|
81
|
+
# # <figure data-trix-attachment='{\"sgid\":\"..."\}'>
|
82
|
+
# # <img src="http://example.org/rails/active_storage/.../funny.jpg">
|
83
|
+
# # </figure>
|
84
|
+
# # </div>
|
53
85
|
def to_trix_html
|
54
86
|
body&.to_trix_html
|
55
87
|
end
|
@@ -20,6 +20,6 @@ class CreateActionTextTables < ActiveRecord::Migration[6.0]
|
|
20
20
|
setting = config.options[config.orm][:primary_key_type]
|
21
21
|
primary_key_type = setting || :primary_key
|
22
22
|
foreign_key_type = setting || :bigint
|
23
|
-
[primary_key_type, foreign_key_type]
|
23
|
+
[ primary_key_type, foreign_key_type ]
|
24
24
|
end
|
25
25
|
end
|
@@ -1,31 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionText
|
4
|
-
#
|
6
|
+
# # Action Text Attachable
|
5
7
|
#
|
6
8
|
# Include this module to make a record attachable to an ActionText::Content.
|
7
9
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
10
|
+
# class Person < ApplicationRecord
|
11
|
+
# include ActionText::Attachable
|
12
|
+
# end
|
11
13
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
14
|
+
# person = Person.create! name: "Javan"
|
15
|
+
# html = %Q(<action-text-attachment sgid="#{person.attachable_sgid}"></action-text-attachment>)
|
16
|
+
# content = ActionText::Content.new(html)
|
17
|
+
# content.attachables # => [person]
|
16
18
|
module Attachable
|
17
19
|
extend ActiveSupport::Concern
|
18
20
|
|
19
21
|
LOCATOR_NAME = "attachable"
|
20
22
|
|
21
23
|
class << self
|
22
|
-
# Extracts the
|
24
|
+
# Extracts the `ActionText::Attachable` from the attachment HTML node:
|
23
25
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
26
|
+
# person = Person.create! name: "Javan"
|
27
|
+
# html = %Q(<action-text-attachment sgid="#{person.attachable_sgid}"></action-text-attachment>)
|
28
|
+
# fragment = ActionText::Fragment.wrap(html)
|
29
|
+
# attachment_node = fragment.find_all(ActionText::Attachment.tag_name).first
|
30
|
+
# ActionText::Attachable.from_node(attachment_node) # => person
|
29
31
|
def from_node(node)
|
30
32
|
if attachable = attachable_from_sgid(node["sgid"])
|
31
33
|
attachable
|
@@ -57,23 +59,23 @@ module ActionText
|
|
57
59
|
ActionText::Attachable.from_attachable_sgid(sgid, only: self)
|
58
60
|
end
|
59
61
|
|
60
|
-
# Returns the path to the partial that is used for rendering missing
|
61
|
-
# Defaults to "action_text/attachables/missing_attachable".
|
62
|
+
# Returns the path to the partial that is used for rendering missing
|
63
|
+
# attachables. Defaults to "action_text/attachables/missing_attachable".
|
62
64
|
#
|
63
65
|
# Override to render a different partial:
|
64
66
|
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
67
|
+
# class User < ApplicationRecord
|
68
|
+
# def self.to_missing_attachable_partial_path
|
69
|
+
# "users/missing_attachable"
|
70
|
+
# end
|
68
71
|
# end
|
69
|
-
# end
|
70
72
|
def to_missing_attachable_partial_path
|
71
73
|
ActionText::Attachables::MissingAttachable::DEFAULT_PARTIAL_PATH
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
|
-
# Returns the Signed Global ID for the attachable. The purpose of the ID is
|
76
|
-
#
|
77
|
+
# Returns the Signed Global ID for the attachable. The purpose of the ID is set
|
78
|
+
# to 'attachable' so it can't be reused for other purposes.
|
77
79
|
def attachable_sgid
|
78
80
|
to_sgid(expires_in: nil, for: LOCATOR_NAME).to_s
|
79
81
|
end
|
@@ -98,30 +100,30 @@ module ActionText
|
|
98
100
|
false
|
99
101
|
end
|
100
102
|
|
101
|
-
# Returns the path to the partial that is used for rendering the attachable
|
102
|
-
#
|
103
|
+
# Returns the path to the partial that is used for rendering the attachable in
|
104
|
+
# Trix. Defaults to `to_partial_path`.
|
103
105
|
#
|
104
106
|
# Override to render a different partial:
|
105
107
|
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
108
|
+
# class User < ApplicationRecord
|
109
|
+
# def to_trix_content_attachment_partial_path
|
110
|
+
# "users/trix_content_attachment"
|
111
|
+
# end
|
109
112
|
# end
|
110
|
-
# end
|
111
113
|
def to_trix_content_attachment_partial_path
|
112
114
|
to_partial_path
|
113
115
|
end
|
114
116
|
|
115
117
|
# Returns the path to the partial that is used for rendering the attachable.
|
116
|
-
# Defaults to
|
118
|
+
# Defaults to `to_partial_path`.
|
117
119
|
#
|
118
120
|
# Override to render a different partial:
|
119
121
|
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
122
|
+
# class User < ApplicationRecord
|
123
|
+
# def to_attachable_partial_path
|
124
|
+
# "users/attachable"
|
125
|
+
# end
|
123
126
|
# end
|
124
|
-
# end
|
125
127
|
def to_attachable_partial_path
|
126
128
|
to_partial_path
|
127
129
|
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/object/try"
|
4
6
|
|
5
7
|
module ActionText
|
6
|
-
#
|
8
|
+
# # Action Text Attachment
|
7
9
|
#
|
8
10
|
# Attachments serialize attachables to HTML or plain text.
|
9
11
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
12
|
+
# class Person < ApplicationRecord
|
13
|
+
# include ActionText::Attachable
|
14
|
+
# end
|
13
15
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
16
|
+
# attachable = Person.create! name: "Javan"
|
17
|
+
# attachment = ActionText::Attachment.from_attachable(attachable)
|
18
|
+
# attachment.to_html # => "<action-text-attachment sgid=\"BAh7CEk..."
|
17
19
|
class Attachment
|
18
20
|
include Attachments::TrixConversion, Attachments::Minification, Attachments::Caching
|
19
21
|
|
@@ -82,29 +84,29 @@ module ActionText
|
|
82
84
|
|
83
85
|
# Converts the attachment to plain text.
|
84
86
|
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
87
|
+
# attachable = ActiveStorage::Blob.find_by filename: "racecar.jpg"
|
88
|
+
# attachment = ActionText::Attachment.from_attachable(attachable)
|
89
|
+
# attachment.to_plain_text # => "[racecar.jpg]"
|
88
90
|
#
|
89
|
-
# Use the
|
91
|
+
# Use the `caption` when set:
|
90
92
|
#
|
91
|
-
#
|
92
|
-
#
|
93
|
+
# attachment = ActionText::Attachment.from_attachable(attachable, caption: "Vroom vroom")
|
94
|
+
# attachment.to_plain_text # => "[Vroom vroom]"
|
93
95
|
#
|
94
96
|
# The presentation can be overridden by implementing the
|
95
|
-
#
|
97
|
+
# `attachable_plain_text_representation` method:
|
96
98
|
#
|
97
|
-
#
|
98
|
-
#
|
99
|
+
# class Person < ApplicationRecord
|
100
|
+
# include ActionText::Attachable
|
99
101
|
#
|
100
|
-
#
|
101
|
-
#
|
102
|
+
# def attachable_plain_text_representation
|
103
|
+
# "[#{name}]"
|
104
|
+
# end
|
102
105
|
# end
|
103
|
-
# end
|
104
106
|
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
107
|
+
# attachable = Person.create! name: "Javan"
|
108
|
+
# attachment = ActionText::Attachment.from_attachable(attachable)
|
109
|
+
# attachment.to_plain_text # => "[Javan]"
|
108
110
|
def to_plain_text
|
109
111
|
if respond_to?(:attachable_plain_text_representation)
|
110
112
|
attachable_plain_text_representation(caption)
|
@@ -115,9 +117,9 @@ module ActionText
|
|
115
117
|
|
116
118
|
# Converts the attachment to HTML.
|
117
119
|
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
120
|
+
# attachable = Person.create! name: "Javan"
|
121
|
+
# attachment = ActionText::Attachment.from_attachable(attachable)
|
122
|
+
# attachment.to_html # => "<action-text-attachment sgid=\"BAh7CEk...
|
121
123
|
def to_html
|
122
124
|
HtmlConversion.node_to_html(node)
|
123
125
|
end
|
@@ -1,39 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionText
|
4
6
|
module Attribute
|
5
7
|
extend ActiveSupport::Concern
|
6
8
|
|
7
9
|
class_methods do
|
8
|
-
# Provides access to a dependent RichText model that holds the body and
|
9
|
-
#
|
10
|
+
# Provides access to a dependent RichText model that holds the body and
|
11
|
+
# attachments for a single named rich text attribute. This dependent attribute
|
12
|
+
# is lazily instantiated and will be auto-saved when it's been changed. Example:
|
13
|
+
#
|
14
|
+
# class Message < ActiveRecord::Base
|
15
|
+
# has_rich_text :content
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# message = Message.create!(content: "<h1>Funny times!</h1>")
|
19
|
+
# message.content? #=> true
|
20
|
+
# message.content.to_s # => "<h1>Funny times!</h1>"
|
21
|
+
# message.content.to_plain_text # => "Funny times!"
|
10
22
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
23
|
+
# The dependent RichText model will also automatically process attachments links
|
24
|
+
# as sent via the Trix-powered editor. These attachments are associated with the
|
25
|
+
# RichText model using Active Storage.
|
14
26
|
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# message.content.to_s # => "<h1>Funny times!</h1>"
|
18
|
-
# message.content.to_plain_text # => "Funny times!"
|
27
|
+
# If you wish to preload the dependent RichText model, you can use the named
|
28
|
+
# scope:
|
19
29
|
#
|
20
|
-
#
|
21
|
-
#
|
30
|
+
# Message.all.with_rich_text_content # Avoids N+1 queries when you just want the body, not the attachments.
|
31
|
+
# Message.all.with_rich_text_content_and_embeds # Avoids N+1 queries when you just want the body and attachments.
|
32
|
+
# Message.all.with_all_rich_text # Loads all rich text associations.
|
22
33
|
#
|
23
|
-
#
|
34
|
+
# #### Options
|
24
35
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
36
|
+
# * `:encrypted` - Pass true to encrypt the rich text attribute. The
|
37
|
+
# encryption will be non-deterministic. See
|
38
|
+
# `ActiveRecord::Encryption::EncryptableRecord.encrypts`. Default: false.
|
28
39
|
#
|
29
|
-
#
|
40
|
+
# * `:strict_loading` - Pass true to force strict loading. When omitted,
|
41
|
+
# `strict_loading:` will be set to the value of the
|
42
|
+
# `strict_loading_by_default` class attribute (false by default).
|
30
43
|
#
|
31
|
-
# * <tt>:encrypted</tt> - Pass true to encrypt the rich text attribute. The encryption will be non-deterministic. See
|
32
|
-
# +ActiveRecord::Encryption::EncryptableRecord.encrypts+. Default: false.
|
33
44
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
45
|
+
# Note: Action Text relies on polymorphic associations, which in turn store
|
46
|
+
# class names in the database. When renaming classes that use `has_rich_text`,
|
47
|
+
# make sure to also update the class names in the
|
48
|
+
# `action_text_rich_texts.record_type` polymorphic type column of the
|
49
|
+
# corresponding rows.
|
37
50
|
def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default)
|
38
51
|
class_eval <<-CODE, __FILE__, __LINE__ + 1
|
39
52
|
def #{name}
|
@@ -60,9 +73,10 @@ module ActionText
|
|
60
73
|
|
61
74
|
# Eager load all dependent RichText models in bulk.
|
62
75
|
def with_all_rich_text
|
63
|
-
|
76
|
+
includes(rich_text_association_names)
|
64
77
|
end
|
65
78
|
|
79
|
+
# Returns the names of all rich text associations.
|
66
80
|
def rich_text_association_names
|
67
81
|
reflect_on_all_associations(:has_one).collect(&:name).select { |n| n.start_with?("rich_text_") }
|
68
82
|
end
|