Skip to content

Commit 6fa5e7a

Browse files
authored
Merge pull request rails#52573 from ghiculescu/at-store_if_blank
Add `store_if_blank` option to `has_rich_text`
2 parents 22fac9a + a0f1d04 commit 6fa5e7a

File tree

4 files changed

+83
-17
lines changed

4 files changed

+83
-17
lines changed

actiontext/CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
* Add `store_if_blank` option to `has_rich_text`
2+
3+
Pass `store_if_blank: false` to not create `ActionText::RichText` records when saving with a blank attribute, such as from an optional form parameter.
4+
5+
```ruby
6+
class Message
7+
has_rich_text :content, store_if_blank: false
8+
end
9+
10+
Message.create(content: "hi") # creates an ActionText::RichText
11+
Message.create(content: "") # does not create an ActionText::RichText
12+
```
13+
14+
*Alex Ghiculescu*
15+
116
* Strip `content` attribute if the key is present but the value is empty
217

318
*Jeremy Green*

actiontext/lib/action_text/attribute.rb

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,16 @@ module Attribute
4141
# `strict_loading:` will be set to the value of the
4242
# `strict_loading_by_default` class attribute (false by default).
4343
#
44+
# * `:store_if_blank` - Pass false to not create RichText records with empty values,
45+
# if a blank value is provided. Default: true.
46+
#
4447
#
4548
# Note: Action Text relies on polymorphic associations, which in turn store
4649
# class names in the database. When renaming classes that use `has_rich_text`,
4750
# make sure to also update the class names in the
4851
# `action_text_rich_texts.record_type` polymorphic type column of the
4952
# corresponding rows.
50-
def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default)
53+
def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default, store_if_blank: true)
5154
class_eval <<-CODE, __FILE__, __LINE__ + 1
5255
def #{name}
5356
rich_text_#{name} || build_rich_text_#{name}
@@ -56,12 +59,26 @@ def #{name}
5659
def #{name}?
5760
rich_text_#{name}.present?
5861
end
59-
60-
def #{name}=(body)
61-
self.#{name}.body = body
62-
end
6362
CODE
6463

64+
if store_if_blank
65+
class_eval <<-CODE, __FILE__, __LINE__ + 1
66+
def #{name}=(body)
67+
self.#{name}.body = body
68+
end
69+
CODE
70+
else
71+
class_eval <<-CODE, __FILE__, __LINE__ + 1
72+
def #{name}=(body)
73+
if body.present?
74+
self.#{name}.body = body
75+
else
76+
self.#{name}.mark_for_destruction if #{name}?
77+
end
78+
end
79+
CODE
80+
end
81+
6582
rich_text_class_name = encrypted ? "ActionText::EncryptedRichText" : "ActionText::RichText"
6683
has_one :"rich_text_#{name}", -> { where(name: name) },
6784
class_name: rich_text_class_name, as: :record, inverse_of: :record, autosave: true, dependent: :destroy,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class MessageWithoutBlanks < ApplicationRecord
2+
self.table_name = Message.table_name
3+
4+
has_rich_text :content, store_if_blank: false
5+
end

actiontext/test/unit/model_test.rb

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,25 @@ class ActionText::ModelTest < ActiveSupport::TestCase
1616
end
1717

1818
test "without content" do
19-
message = Message.create!(subject: "Greetings")
20-
assert_predicate message.content, :nil?
21-
assert_predicate message.content, :blank?
22-
assert_predicate message.content, :empty?
23-
assert_not message.content?
24-
assert_not message.content.present?
19+
assert_difference("ActionText::RichText.count" => 0) do
20+
message = Message.create!(subject: "Greetings")
21+
assert_predicate message.content, :nil?
22+
assert_predicate message.content, :blank?
23+
assert_predicate message.content, :empty?
24+
assert_not message.content?
25+
assert_not message.content.present?
26+
end
2527
end
2628

2729
test "with blank content" do
28-
message = Message.create!(subject: "Greetings", content: "")
29-
assert_not message.content.nil?
30-
assert_predicate message.content, :blank?
31-
assert_predicate message.content, :empty?
32-
assert_not message.content?
33-
assert_not message.content.present?
30+
assert_difference("ActionText::RichText.count" => 1) do
31+
message = Message.create!(subject: "Greetings", content: "")
32+
assert_not message.content.nil?
33+
assert_predicate message.content, :blank?
34+
assert_predicate message.content, :empty?
35+
assert_not message.content?
36+
assert_not message.content.present?
37+
end
3438
end
3539

3640
test "embed extraction" do
@@ -123,4 +127,29 @@ class ActionText::ModelTest < ActiveSupport::TestCase
123127
assert_equal "Body", message.body.to_plain_text
124128
end
125129
end
130+
131+
test "with blank content and store_if_blank: false" do
132+
assert_difference("ActionText::RichText.count" => 0) do
133+
message = MessageWithoutBlanks.create!(subject: "Greetings", content: "")
134+
assert_predicate message.content, :nil?
135+
assert_predicate message.content, :blank?
136+
assert_predicate message.content, :empty?
137+
assert_not message.content?
138+
assert_not message.content.present?
139+
end
140+
end
141+
142+
test "if allowing blanks, updates rich text record on edit" do
143+
message = Message.create!(subject: "Greetings", content: "content")
144+
assert_difference("ActionText::RichText.count" => 0) do
145+
message.update(content: "")
146+
end
147+
end
148+
149+
test "if disallowing blanks, deletes rich text record on edit" do
150+
message = MessageWithoutBlanks.create!(subject: "Greetings", content: "content")
151+
assert_difference("ActionText::RichText.count" => -1) do
152+
message.update(content: "")
153+
end
154+
end
126155
end

0 commit comments

Comments
 (0)