Add guidance to the Association Basics and `.belongs_to` method
documentation to encourage the renaming of a model's Ruby class to
coincide with updates to the existing data in the database.
Since Action Text and Active Storage rely on polymorphic associations,
add similar warnings to their guides.
Co-authored-by: Petrik de Heus <petrik@deheus.net>
Co-authored-by: Stephen Hanson <s.hanson5@gmail.com>
Co-authored-by: zzak <zzakscott@gmail.com>
actiontext.js is compiled as ESM bundle instead of UMD bundle.
This leads to issues when trying to use ActionText with sprockets because the ESM bundle declares variables like they are scoped to the file but sprockets will see them as scoped globally.
This is a problem, in particular, if you want to mix actiontext with
turbo-rails.
The problem got introduced in https://github.com/rails/rails/pull/46447.
I traced valid compilation back to
https://github.com/rails/rails/pull/42895.
This commit mimic changes made in
https://github.com/rails/rails/pull/42895 to ActiveStorage:
Retains app/assets/javascripts/actiontext.js as a UMD package for backwards compatibility with
bundling in the asset pipeline, but also adds app/assets/javascripts/actiontext.esm.js for use
with ESM via importmap in the browser.
Add documentation for `ActionText::RichText#to_s` and
`ActionText::Content#to_s` that demonstrates Action Text's ability to
sanitize and scrub its content.
Co-authored-by: Mike Dalessio <mike.dalessio@gmail.com>
Co-authored-by: Petrik de Heus <petrik@deheus.net>
* Add Bun support to `rails new -j` generator
* Add additional generation consideration for Bun
* Use development gems to test the whole workflow
* Remove custom gems from local testing
* Revert lock
* Revert errant custom gem declaration
* Fix linting errors
* Fix remnants of bad merge
* Always use latest bun
* Update actioncable/lib/rails/generators/channel/channel_generator.rb
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
* Update guides/source/working_with_javascript_in_rails.md
Co-authored-by: Rafael Mendonça França <rafael@franca.dev>
* Only use the latest bun if nothing is specified
* Hardcode known good version
---------
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
Co-authored-by: Rafael Mendonça França <rafael@franca.dev>
Using `initializer` in the engine may run the block before application
initializers. Instead, use `config.after_initialize` to ensure that
application initializers take effect properly.
Also, don't bother deleting the config value, since that pattern isn't
needed here (as it is in other railties like action_view/railtie.rb).
The change from `#clone` to `#dup` is necessary to work around an
issue in Nokogiri where `#clone` is not defined properly for HTML5
fragment and the fragment does not have a parent Document. `#dup`
behaves the way we expect, so this should be fine.
Currently when opening the main framework pages there is no introduction
to the framework. Instead we only see a whole lot of modules and the
`gem_version` and `version` methods.
By including the READMEs using the `:include:` directive each frameworks
has a nice introduction.
For markdown READMEs we need to add the :markup: directive.
[ci-skip]
Co-authored-by: zzak <zzakscott@gmail.com>
Before this commit, using ActionText and calling `#as_json` on a
non-persisted `ActiveStorage::Blob` raised an error.
This is because `ActionText::Attachable` is included in
`ActiveStorage::Blob` and overrides the `#as_json` method to
expose a global signed id. However, a global signed id can only
be generated on a persisted instance.
This commit fixes the issue by making sure the blob is persisted
before exposing the global signed id.
Running `bin/rails action_text:install` appends `import "trix"` to the `application.js` file without inserting a newline.
In my app this resulted in the following:
```js
// import statements....
import Rails from "@rails/ujs"
Rails.start()import "trix"
import "@rails/actiontext"
```
I assume this bug occurred because my `application.js` was listed at some point and removed an extra line, which was not expected by this generator.
I recommend prepending the string to be inserted with a `\n` just to be safe.
This represents a +2x performance optimization when the replacement
logic is based on some condition, and it returns the same unchanged
node when it wants to skip it:
```ruby
html = <<~HTML
<div>
#{'<p>ignore me</p>' * 1000}
#{'<p>replace me</p>' * 1000}
</div>
HTML
content = content_from_html(html)
replacement_example = -> do
content.fragment.replace("p") do |node|
if node.text =~ /replace me/
"<p>replace me</p>"
else
node
end
end
end
current_implementation = -> do
class ActionText::Fragment
def replace(selector)
update do |source|
source.css(selector).each do |node|
replacement_node = yield(node)
node.replace(replacement_node.to_s)
end
end
end
end
replacement_example.call
end
new_implementation = -> do
class ActionText::Fragment
def replace(selector)
update do |source|
source.css(selector).each do |node|
replacement_node = yield(node)
node.replace(replacement_node.to_s) if node != replacement_node
end
end
end
end
replacement_example.call
end
Benchmark.ips do |x|
x.report "Current implementation", ¤t_implementation
x.report "New implementation", &new_implementation
x.compare!
end
```
Results:
```
Warming up --------------------------------------
Current implementation
2.000 i/100ms
New implementation 5.000 i/100ms
Calculating -------------------------------------
Current implementation
32.484 (±30.8%) i/s - 134.000 in 5.036419s
New implementation 74.878 (±38.7%) i/s - 250.000 in 5.052168s
Comparison:
New implementation: 74.9 i/s
Current implementation: 32.5 i/s - 2.31x (± 0.00) slower
```
When System Tests call `fill_in_rich_text_area`, they interact with
`<trix-editor>` elements by changing the contents programmatically.
This is unlike how end-users will interact with the element. Overhauling
the test helper to more accurately reflect Real World usage would
require a sizable effort.
With that being said, leaving the `<trix-editor>` with focus after
populating its contents is a minor change that makes it a more genuine
recreation.
Since engine initializers run later in the process, we need to run this
initializer earlier than the default.
This ensures they're all registered before the environments are loaded.
Because they are CamelCase, RDoc will automatically link these
references. Automatic links have monospace formatting, whereas, in some
cases, manual links do not.
This commit adds `ActionText.deprecator`, and adds it to
`Rails.application.deprecators` so that it can be configured via
settings such as `config.active_support.report_deprecations`.
Expand the `has_rich_text` signature to accept a `strict_loading:`
value. Forward that value along to the `has_one` declaration made under
the hood. When omitted, `strict_loading:` will be set to the value of
the `strict_loading_by_default` class attribute (false by default).
Follow-up to #45144.
This ensures that a renderer is always available for Action Text, even
when `ActionController::Base` was not previously loaded.
Fixes#46113.
As with #45144, this still avoids loading `ActionController::Base`
unnecessarily when rendering mail after Action Text has been loaded.
**Before:**
```
$ bin/rails r 'Benchmark.memory { |x| x.report("load"){ MyBlankMailer.blank_email.body } }'
Calculating -------------------------------------
load 4.466M memsize ( 1.205M retained)
29.202k objects ( 11.943k retained)
50.000 strings ( 50.000 retained)
```
**After:**
```
$ bin/rails r 'Benchmark.memory { |x| x.report("load"){ MyBlankMailer.blank_email.body } }'
Calculating -------------------------------------
load 4.462M memsize ( 1.205M retained)
29.141k objects ( 11.940k retained)
50.000 strings ( 50.000 retained)
```
Co-authored-by: Christopher Louvet <cl@nonplaces.com>
this makes it possible for an application to embed markup in a document
that would otherwise be undesirable or expensive to process. For example,
an incoming email may include a complicated bit of DOM in a quote, and
while you don't want to have to process and rewrite it, you also don't want
to discard it; the content attribute of ContentAttachment allows you to
make that work.
RDoc will automatically format and link API references as long as they
are not already marked up as inline code.
This commit removes markup from various API references so that those
references will link to the relevant API docs.
Prior to this commit, `ActionText::Content#inspect` called `#to_s` and
truncated the result to 25 characters. However, `#to_s` calls
`#to_rendered_html_with_layout` which, by default, renders the same
first 25 characters for every instance.
For example, with models such as:
```ruby
class Message < ActiveRecord::Base
has_rich_text :content
end
Message.create(content: "first message")
Message.create(content: "second message")
Message.create(content: "third message")
```
The output of `#inspect` is indistinguishable:
```irb
irb> Message.all.map { |message| message.content.body }
Rendered .../actiontext/app/views/action_text/contents/_content.html.erb within layouts/action_text/contents/_content (Duration: 2.4ms | Allocations: 881)
Rendered .../actiontext/app/views/action_text/contents/_content.html.erb within layouts/action_text/contents/_content (Duration: 0.7ms | Allocations: 257)
Rendered .../actiontext/app/views/action_text/contents/_content.html.erb within layouts/action_text/contents/_content (Duration: 0.6ms | Allocations: 257)
=> [#<ActionText::Content "<div class=\"trix-conte...">,
#<ActionText::Content "<div class=\"trix-conte...">,
#<ActionText::Content "<div class=\"trix-conte...">]
```
This commit changes `#inspect` to call `#to_html`, which does not render
the Action Text layout. So the output of `#inspect` will be:
```irb
irb> Message.all.map { |message| message.content.body }
=> [#<ActionText::Content "first message">,
#<ActionText::Content "second message">,
#<ActionText::Content "third message">]
```