Skip to content

Commit

Permalink
Add store_if_blank option to has_rich_text
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiculescu authored and rafaelfranca committed Aug 21, 2024
1 parent 688b0a7 commit a0f1d04
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
15 changes: 15 additions & 0 deletions actiontext/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
* Add `store_if_blank` option to `has_rich_text`

Pass `store_if_blank: false` to not create `ActionText::RichText` records when saving with a blank attribute, such as from an optional form parameter.

```ruby
class Message
has_rich_text :content, store_if_blank: false
end

Message.create(content: "hi") # creates an ActionText::RichText
Message.create(content: "") # does not create an ActionText::RichText
```

*Alex Ghiculescu*

* Strip `content` attribute if the key is present but the value is empty

*Jeremy Green*
Expand Down
27 changes: 22 additions & 5 deletions actiontext/lib/action_text/attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ module Attribute
# `strict_loading:` will be set to the value of the
# `strict_loading_by_default` class attribute (false by default).
#
# * `:store_if_blank` - Pass false to not create RichText records with empty values,
# if a blank value is provided. Default: true.
#
#
# Note: Action Text relies on polymorphic associations, which in turn store
# class names in the database. When renaming classes that use `has_rich_text`,
# make sure to also update the class names in the
# `action_text_rich_texts.record_type` polymorphic type column of the
# corresponding rows.
def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default)
def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default, store_if_blank: true)
class_eval <<-CODE, __FILE__, __LINE__ + 1
def #{name}
rich_text_#{name} || build_rich_text_#{name}
Expand All @@ -56,12 +59,26 @@ def #{name}
def #{name}?
rich_text_#{name}.present?
end
def #{name}=(body)
self.#{name}.body = body
end
CODE

if store_if_blank
class_eval <<-CODE, __FILE__, __LINE__ + 1
def #{name}=(body)
self.#{name}.body = body
end
CODE
else
class_eval <<-CODE, __FILE__, __LINE__ + 1
def #{name}=(body)
if body.present?
self.#{name}.body = body
else
self.#{name}.mark_for_destruction if #{name}?
end
end
CODE
end

rich_text_class_name = encrypted ? "ActionText::EncryptedRichText" : "ActionText::RichText"
has_one :"rich_text_#{name}", -> { where(name: name) },
class_name: rich_text_class_name, as: :record, inverse_of: :record, autosave: true, dependent: :destroy,
Expand Down
5 changes: 5 additions & 0 deletions actiontext/test/dummy/app/models/message_without_blanks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class MessageWithoutBlanks < ApplicationRecord
self.table_name = Message.table_name

has_rich_text :content, store_if_blank: false
end
53 changes: 41 additions & 12 deletions actiontext/test/unit/model_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,25 @@ class ActionText::ModelTest < ActiveSupport::TestCase
end

test "without content" do
message = Message.create!(subject: "Greetings")
assert_predicate message.content, :nil?
assert_predicate message.content, :blank?
assert_predicate message.content, :empty?
assert_not message.content?
assert_not message.content.present?
assert_difference("ActionText::RichText.count" => 0) do
message = Message.create!(subject: "Greetings")
assert_predicate message.content, :nil?
assert_predicate message.content, :blank?
assert_predicate message.content, :empty?
assert_not message.content?
assert_not message.content.present?
end
end

test "with blank content" do
message = Message.create!(subject: "Greetings", content: "")
assert_not message.content.nil?
assert_predicate message.content, :blank?
assert_predicate message.content, :empty?
assert_not message.content?
assert_not message.content.present?
assert_difference("ActionText::RichText.count" => 1) do
message = Message.create!(subject: "Greetings", content: "")
assert_not message.content.nil?
assert_predicate message.content, :blank?
assert_predicate message.content, :empty?
assert_not message.content?
assert_not message.content.present?
end
end

test "embed extraction" do
Expand Down Expand Up @@ -123,4 +127,29 @@ class ActionText::ModelTest < ActiveSupport::TestCase
assert_equal "Body", message.body.to_plain_text
end
end

test "with blank content and store_if_blank: false" do
assert_difference("ActionText::RichText.count" => 0) do
message = MessageWithoutBlanks.create!(subject: "Greetings", content: "")
assert_predicate message.content, :nil?
assert_predicate message.content, :blank?
assert_predicate message.content, :empty?
assert_not message.content?
assert_not message.content.present?
end
end

test "if allowing blanks, updates rich text record on edit" do
message = Message.create!(subject: "Greetings", content: "content")
assert_difference("ActionText::RichText.count" => 0) do
message.update(content: "")
end
end

test "if disallowing blanks, deletes rich text record on edit" do
message = MessageWithoutBlanks.create!(subject: "Greetings", content: "content")
assert_difference("ActionText::RichText.count" => -1) do
message.update(content: "")
end
end
end

0 comments on commit a0f1d04

Please sign in to comment.