Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for broadcast methods to accept a renderable #364

Merged
merged 6 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/channels/turbo/streams/broadcasts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,6 @@ def broadcast_stream_to(*streamables, content:)

private
def render_format(format, **rendering)
ApplicationController.render(formats: [ format ], **rendering)
ApplicationController.render(layout: false, formats: [ format ], **rendering)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed if we also set o[:layout] = false in broadcastable#368?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. It doesn't seem like its needed so I nixed it:

58f8427

end
end
15 changes: 14 additions & 1 deletion app/models/concerns/turbo/broadcastable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@
# end
# end
#
# If you want to render a renderable object you can use the `renderable:` option.
#
# class Message < ApplicationRecord
# belongs_to :user
#
# after_create_commit :update_message
#
# private
# def update_message
# broadcast_replace_to(user, :message, target: "message", renderable: MessageComponent.new)
# end
# end
#
# There are four basic actions you can broadcast: <tt>remove</tt>, <tt>replace</tt>, <tt>append</tt>, and
# <tt>prepend</tt>. As a rule, you should use the <tt>_later</tt> versions of everything except for remove when broadcasting
# within a real-time path, like a controller or model, since all those updates require a rendering step, which can slow down
Expand Down Expand Up @@ -352,7 +365,7 @@ def broadcast_rendering_with_defaults(options)

if o[:html] || o[:partial]
return o
elsif o[:template]
elsif o[:template] || o[:renderable]
o[:layout] = false
else
# if none of these options are passed in, it will set a partial from #to_partial_path
Expand Down
13 changes: 13 additions & 0 deletions test/dummy/app/components/message_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class MessageComponent
def initialize(text)
@text = text
end

def render_in(view_context)
"<div class='test-message'>#{@text}</div>".html_safe
end

def format
:html
end
end
18 changes: 18 additions & 0 deletions test/system/broadcasts_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ class BroadcastsTest < ApplicationSystemTestCase
end
end

test "Message broadcasts with renderable: render option" do
visit messages_path
wait_for_stream_to_be_connected

assert_broadcasts_text "Test message", to: :messages do |text, target|
Message.create(content: "Ignored").broadcast_append_to(target, renderable: MessageComponent.new(text))
end
end

test "Does not render the layout twice when passed a component" do
visit messages_path
wait_for_stream_to_be_connected

Message.create(content: "Ignored").broadcast_append_to(:messages, renderable: MessageComponent.new("test"))

assert_selector("title", count: 1, visible: false, text: "Dummy")
end

test "Users::Profile broadcasts Turbo Streams" do
visit users_profiles_path
wait_for_stream_to_be_connected
Expand Down