hotwired / turbo-rails Goto Github PK
View Code? Open in Web Editor NEWUse Turbo in your Ruby on Rails app
Home Page: https://turbo.hotwired.dev
License: MIT License
Use Turbo in your Ruby on Rails app
Home Page: https://turbo.hotwired.dev
License: MIT License
Hello,
Turbolinks removed, with turbo-rails how will you replace this line previously used :
document.addEventListener('turbolinks:load', () => initWebsite());
Thanks :)
Only getting the above error when I try and deploy to production, and works fine in development. It may be something that's conflicting, i've disabled the old turbolinks and UJS import and start, using turbo in the asset pipeline...any clues on where i should start to look to fix this? - turning off eager loading allows the app to launch
Any specific reason turbo-rails/app/helpers/turbo/drive_helper.rb only has a method to set no-cache
but not no-preview
?
Hey guys,
I have an app with turbo-rails
gem and Im *not using webpack.
On application.html
layout I have:
<%= turbo_include_tags %>
<%= stimulus_include_tags %>
but when trying to call Turbo
inside stimulus controller (or on browser console) I got the error:
Turbo is not defined
I saw that on response its export { turbo_es2017Esm as Turbo, cable };
but since Im not using webpack I dont think its going to be exported to window
object ?
Thanks
I tried to install hotwire-rails
in a fresh Rails 6.0.3 application and follow the screencast steps one by one.
I run rails hotwire:install
worked as supposed to. The path it followed was the webpacker
one as defined in lib/install/turbo_with_webpacker.rb
.
However, for some reason, the turbo-frame
auto-append behaviour after creating a message was missing, I had to reload the page to see the new message in the page. After some investigation, I realised that the <%= turbo_include_tags %>
clause was missing from application.html.erb
. By adding the clause, everything works as expected.
This omission is expected by the code, since it does not add the clause like in lib/install/turbo_with_asset_pipeline.rb
.
Am I missing something? Is the webpacker path supposed to work without adding the <%= turbo_include_tags %>
clause manually?
I would be happy to open a PR, to either update documentation or fix the installation process.
Thoughts?
Hi,
This works:
class Post < ApplicationRecord
belongs_to :room
after_create_commit -> { broadcast_prepend_to :room }
def broadcast_target_default
"#{model_name.plural}_#{self.priority}"
end
end
This doesn't:
class Post < ApplicationRecord
belongs_to :room
broadcasts_to :room
def broadcast_target_default
"#{model_name.plural}_#{self.priority}"
end
end
Probably cause https://github.com/hotwired/turbo-rails/blob/main/app/models/concerns/turbo/broadcastable.rb#L61 is init to model_name.plural
.
I would expect same behavior and both methods to read broadcast_target_default
. Hope this make sense !
Regards
DEPRECATION WARNING: Initialization autoloaded the constants Turbo::Streams, Turbo::Streams::TurboStreamsTagBuilder, Turbo::Frames, Turbo::Frames::FrameRequest, Turbo::Native, Turbo::Native::Navigation, Turbo::DriveHelper, Turbo::FramesHelper, Turbo::IncludesHelper, Turbo::StreamsHelper, Turbo::Streams::ActionHelper, and Turbo::Broadcastable.
Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.
Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload Turbo::Streams, for example,
the expected changes won't be reflected in that stale Module object.
These autoloaded constants have been unloaded.
Please, check the "Autoloading and Reloading Constants" guide for solutions.
(called from <top (required)> at /config/environment.rb:7)
Hold on, I am eager loading the application.
rails aborted!
Hi hope you're having a good day.
So i have updated my dependies to run Hotwire and replaced the old turbolinks
with turbo
and since the the Rails Action text trix-editor
isnot appearing on the UI i get an empty container.
here is the code for rendering a form
<%= form_for [current_user, @project, @todolist], html: {class: "w-full"} do |f| %>
<%= hidden_field_tag :parent_id, current_user.id %>
<%= hidden_field_tag :project_id, @project.id %>
<%= f.text_field :name, class: "text--darker font-medium w-full border-b border-transparent placeholder-gray-600 pb-1 focus:outline-none focus:border-gray-500 my-2" , placeholder: "Type the name here"%>
<section class="hidden" data-todos-target="description">
<%= f.rich_text_area :description, class: "w-full my-2" %>
</section>
and i get this error in the console
this is the content of app/javascript/packs/application.js
file
// require("@rails/ujs").start()
// require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("trix")
require("@rails/actiontext");
import "css/application.scss"
import "controllers"
import { Turbo, cable } from "@hotwired/turbo-rails"
Thank you for your time
Importing with ESM doesn't seem to work with the rails asset pipeline
The following throws an error about the package not being found
import { Turbo } from 'turbo'
I set up a rails app with the --skip-javascript
option and ran rails turbo:install
Importing stimulus works but I cant seem to import turbo.
I also tried this package name which also doesn't work
import { Turbo, cable } from "@hotwired/turbo-rails"
Am I missing something?
Hi,
I had to do
module ApplicationHelper
# Should be autoloaded..
include Turbo::StreamsHelper
include Turbo::FramesHelper
...
end
because i was hitting those errors:
undefined method `turbo_stream_from' for #<ActionView::Base:0x0000000004fab0>
undefined method `turbo_frame_tag' for #<ActionView::Base:0x0000000004e700>
I would expect those to be auto-loaded ?
Rails 6.1.0
Gemfile.lock
hotwire-rails (0.1.2)
rails (>= 6.0.0)
stimulus-rails
turbo-rails
turbo-rails (0.5.2)
rails (>= 6.0.0)
Regards
I'm seeing strange behavior when rendering a partial from a turbo stream response.
This example almost directly mirrors the use case documented in the #turbo_stream
method of app/helpers/turbo/streams_helper.rb
.
I'm using haml
in my project, but have tried transitioning everything to erb
and still receive the same error.
I've got a controller that attempts to create a thing, and responds to turbo_stream
or html
formats.
# organization/scheduled_schedule_items_controller
def create
@scheduled_schedule_item = @schedule.scheduled_schedule_items
.build(scheduled_schedule_item_params)
@scheduled_schedule_item.save
respond_to do |format|
format.turbo_stream
format.html { redirect_to schedule_organization_schedule_path(@schedule) }
end
end
I've got a create.turbo_stream.haml
template that is attempting to render a partial.
- # organization/scheduled_schedule_items/create.turbo_stream.haml
- date = @scheduled_schedule_item.item_start_date_as_date
= turbo_stream.replace "schedule-item-modal-form-for-#{date}" do
- if @scheduled_schedule_item.persisted?
%p.text-success Success!
- else
= render 'modal_form', schedule: @schedule, schedule_item: @scheduled_schedule_item, date: date
I receive the following error that the partial (Which is definitely in the right place) can't be found. Seemingly because :formats
only include [:turbo_stream]
.
ActionView::Template::Error (Missing partial organization/scheduled_schedule_items/_modal_form, organization/base/_modal_form, application/_modal_form with {:locale=>[:en], :formats=>[:turbo_stream], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :haml, :jbuilder]}. Searched in:
* "/app/app/views"
* "/usr/local/bundle/gems/actiontext-6.1.1/app/views"
* "/usr/local/bundle/gems/actionmailbox-6.1.1/app/views"
):
5: <p class="text-success">Success!</p>
6:
7: <% else %>
8: <%= render 'modal_form', schedule: @schedule, schedule_item: @scheduled_schedule_item, date: date %>
9:
10: <% end %>
11: <% end %>
If I change the format of my partial render to the below, everything works.
- # organization/scheduled_schedule_items/create.turbo_stream.haml
= render partial: 'modal_form', formats: [:html], locals: { schedule: @schedule, schedule_item: @scheduled_schedule_item, date: date }
This seems out of the ordinary for two reasons:
#turbo_stream
method renders a partial in its response and doesn't explicitly need to include this formats: [:html]
bit.create.js.erb
template would have no issue rendering a .haml
or .html.erb
partial using something like <%=j render 'form' %>
.Am I missing something obvious here? Thank you.
In our application, we use an explicit call to ActionController::Base.new.render_to_string('partial_name')
to render a partial into a string and do stuff with it.
This now causes a call to turbo_frame_request?
but since there is no request
. boom.
My proposal would be to change it to request&.headers.try(:[], "Turbo-Frame").present?
I was trying to run the install instructions against the Webpacker 6 beta.
Taking my example which already worked against Webpacker 5, and upgrading Webpacker, my Turbo install was no longer downloading. (The links that had been identified in the log as being processed as TURBO_STREAM
no longer were, the behavior was no longer working, and Turbo was no longer in the sources tab).
Adding a console.log(Turbo)
to the application.js
file makes everything work again, so I guess I'd assume that the switch to Webpacker 6 and the javascript_packs_with_chunks_tag
helper somehow doesn't realize that Turbo is being used and therefore doesn't download it with the pack?
Is there a preferred way of managing this?
Thanks!
Hi,
Can you advise of the annotation "data-turbolinks-track": "reload"
in javascript_pack_tag/stylesheet_link_tag
tag?
Should we remove? rename to data-turbo-track
?
Thanks for sharing the library.
Through trial and error I realised that a controller action can return multiple turbo streams. An example would be if you want to append an item to a list, and also show an alert that the item was created.
The syntax is a bit funky if you do it through a controller:
respond_to do |format|
format.turbo_stream do
render turbo_stream: [
turbo_stream.replace(:flash, partial: "layouts/flash", locals: { notice: "Message posted!" }),
turbo_stream.append(:messages, partial: "messages/message", locals: { message: message })
]
end
end
(you could also do it through a .turbo_stream.erb
file, but I like having this in the controller)
Questions:
respond_to do |format|
format.turbo_stream do
render turbo_stream: turbo_stream
.replace(:flash, partial: "layouts/flash", locals: { notice: "Message posted!" })
.append(:messages, partial: "messages/message", locals: { message: message })
end
end
Should the installation instructions include changing:
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
to
<%= javascript_pack_tag 'application', 'data-turbo-track': 'reload' %>
?
Just found these:
If we use the link_to
tag with method: :post
it redirects instead of rendering inside the turbo_frame (get works fine)
whereas `button_to' displays usual behaviour by rendering it inside the turbo_frame
link_to...do
always redirects to a new page
Are these the usual behaviors, I'm totally new, watching a lot of tutorials here
I think it's a bit misleading that there is no information about how Turbo is and isn't backwards compatible with Turbolinks since installing Turbo removes Turbolinks. I'm not sure if the final release version is planned to be backwards compatible, but if not, I think a list of things that are not compatible would be very helpful for people upgrading to Turbo.
Let's say I have the following in a template:
<%= link_to "Sign out", signout_path, method: :delete %>
When I click on it, I'll get a routing error that seems to reflect the link having been visited with a GET
rather than a DELETE
request. I believe that this means that turbo-rails
is not picking up on the data-method
in the rendered link.
It would be fantastic to make render turbo_stream:
use an optional layout
This way, we can have global-level stream updates that make sense on every page.
For instance, our layout could look like this :
<% if flash[:success].present? %>
<%= turbo_stream.replace("flash_success") do %>
<%= render "flash/success" %>
<% end %>
<% end>
<%= yield %>
Allowing our controller to use flash regardless of the format and then have the layout pick it up either in the stream or in the template.
WDYT ? Happy to provide a PR
Turbo::Native::Navigation
's comment says "see the Turbo iOS and Turbo Android projects for details".
https://github.com/hotwired/turbo-rails/blob/v0.5.3/app/controllers/turbo/native/navigation.rb#L1-L3
But I could not find code that handle recede
, resume
, refresh
in turbo-ios or turbo-android.
turbo-rails
include Turbo::Native::Navigation
?After use turbo, got error message Error: Form responses must redirect to another location
if submit form fail
post.rb
class Post < ApplicationRecord
validates :title, presence: true, uniqueness: { case_sensitive: false }
end
# POST /posts
# POST /posts.json
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to @post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
<h1>New Post</h1>
<%= render 'form', post: @post %>
<%= link_to 'Back', posts_path %>
The turbo:install
command was designed for the asset pipeline. Let's create two new commands: turbo:install:asset_pipeline
and turbo:install:webpacker
. Then we'll make turbo:install
delegate to the right one, depending on whether Webpacker is active in the app.
The turbo:install:webpacker
command should make the following changes:
While I am porting my application to Turbo, I run into an issue.
This is the code I've got so far:
The .erb template:
<%= turbo_frame_tag dom_id(vehicle) do %>
<%= turbo_stream_from vehicle %>
... some template code ...
<%= image_tag vehicle.image.variant(resize_to_fill: [424, 220]) %>
<% end %>
<% end %>
In my model:
after_update_commit :broadcast_later
def broadcast_later
broadcast_replace partial: "customer/dashboard/vehicle"
end
This all seems to work great, except for one thing, the image I had in the DOM uses the wrong host after it's being replaced. The initial load uses the right URL, but when it's replaced by a broadcast it changes to example.org.
Before | After |
---|---|
I also created this initializer:
ActiveSupport::Reloader.to_prepare do
ApplicationController.renderer.defaults.merge!(
http_host: Rails.application.config.action_controller.asset_host
)
end
I hope you have any idea what the solution could be, thanks!
Hi.
I'm triying to install turbo-rails
following the README instructions. I'm using webpacker
instead of asset-pipeline.
After install turbo-rails
gem and add @hotwired/turbo-rails
, when I try to import Turbo and cable in application.js, Webpacker fails compilation with following message:
webpacker | ERROR in ./node_modules/@hotwired/turbo-rails/app/javascript/turbo/index.js 2:9
webpacker | Module parse failed: Unexpected token (2:9)
webpacker | File was processed with these loaders:
webpacker | * ./node_modules/babel-loader/lib/index.js
webpacker | You may need an additional loader to handle the result of these loaders.
webpacker | | import "./cable_stream_source_element";
webpacker | > export * as Turbo from "@hotwired/turbo";
webpacker | | export * as cable from "./cable";
webpacker | โน ๏ฝขwdm๏ฝฃ: Failed to compile.
I tried restarting the server, and re-installing dependencies.
Not sure how to word this.
If you have a partial:
# _foobar.html.erb
<%= turbo_stream_from model %>
and in a controller action, you're replacing that partial
def do_something
@model.broadcast_replace partial: "examples/foobar", locals: { model: @model }
end
The turbo-cable-stream-source
element will get duplicated exponentially.
Thor::Error: The file /app/views/layouts/application.html.erb does not appear to exist
/usr/local/bundle/gems/thor-1.0.1/lib/thor/actions/inject_into_file.rb:67:in `invoke!'
/usr/local/bundle/gems/thor-1.0.1/lib/thor/actions.rb:93:in `action'
/usr/local/bundle/gems/thor-1.0.1/lib/thor/actions/inject_into_file.rb:32:in `insert_into_file'
/usr/local/bundle/gems/turbo-rails-0.5.0/lib/install/turbo.rb:2:in `apply'
/usr/local/bundle/gems/thor-1.0.1/lib/thor/actions.rb:227:in `instance_eval'
/usr/local/bundle/gems/thor-1.0.1/lib/thor/actions.rb:227:in `apply'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/tasks/framework.rake:15:in `block (2 levels) in <top (required)>'
/usr/local/bundle/gems/appsignal-2.11.1/lib/appsignal/hooks/rake.rb:18:in `execute'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/command.rb:48:in `invoke'
/usr/local/bundle/gems/railties-6.0.3.4/lib/rails/commands.rb:18:in `<top (required)>'
./bin/rails:4:in `require'
./bin/rails:4:in `<main>'
Tasks: TOP => app:template
Hi,
Is there a version missmatch of turbo and turbo-rails?
I've updated the gem to v0.5.7 however running ./bin/rails turbo:install
is not installing the latest version(7.0.0-beta.4) of "@hotwired/turbo-rails" because it is not available yet. https://yarnpkg.com/package/@hotwired/turbo-rails shows that the latest version is 7.0.0-beta.3.
turbo-rails 7.0.0-beta.3. is dependent on "@hotwired/turbo": "^7.0.0-beta.2". With yarn install however @hotwired/turbo": "^7.0.0-beta.3" is installed.
Hello,
I thought I had read something about data-disable-with related to turbo-rails, but I can't find it in my history anywhere. I notice that data: { disable_with: '...' }
doesn't seem to work anymore when making the transition to turbo-rails from turbolinks and rails-ujs.
I wasn't quite sure what made data-disable-with work in the past, but I'm assuming it was rails-ujs since it doesn't seem to be related to turbolinks and the only other thing I removed to make way for turbo-rails was rails-ujs.
Are we planning on having data-disable-with functionality restored? Or is this something we should implement ourselves from here on out?
I've really enjoyed learning about the new magic, thanks for all the efforts!
Bonjour,
On my localhost, this error doesn't show up but on heroku, it's shows.
Is someone have any idea ?
Thanks for your time.
Cordialement,
I understand completely it's a way more Devise thing than Basecamp's, but anyway.
Quite simple setup: @posts on the page, form for adding new posts, a post has likes count (from gem 'acts_as_voteable'
). Guests are unable to like posts, so the post partial has user_signed_in?
method from Devise. Cable doesn't know anything from Devise, sessions, etc, so it's saying Devise::MissingWarden in Posts#create, and a freshly created post is never broadcasted.
Any ideas how to solve this?
Best.
p.s. Thanks for Hotwire and the team's efforts anyway! Overall, looks and feels just mind-blowing.
First of all, thanks to all of the developers on this project for this lovely holiday surprise gift.
I am part of a small team of developers and today we were playing with adding some javascript/css that would add some minimal styling of turbo-frames for debugging/learning purposes. This mostly worked well when hooking into a turbo:load event; however, when just a frame was being replaced we found that there was not an event we could handle in order to update an attribute on the frame being used for debugging. Is there a way to hook into the replace event?
Also, I am very excited about the direction of hotwire and would like to contribute in some way that would be helpful while also giving me a better understanding of the internals of the code. What is the best way to get involved at this time?
I'm trying to Turboify an app which uses Devise.
When I try to sign out, I expect the following to happen.
Instead, the following happens:
For my use case, I can probably fix it by overriding the Devise redirect chain -- it's annoying, but not unsolvable.
However, I can see this kind of interaction being really confusing to a naive user. It doesn't really signal what the issue is, it's just a silent failure.
Hello,
I have a button that POSTs to a route in my app:
<%= button_to "/auth/github", data: { turbo: false } do %>
Sign in with GitHub
<% end %>
I added data-turbo="false"
to the button to make sure users are properly redirected to GitHub. But when I click the button, an XHR request is fired off to the endpoint with turbo
being shown as the initiator.
I tried adding data-turbo="false"
to the button's parent element to see if that would fix it, but that's not the case either.
When I remove <%= turbo_include_tags %>
from my layout, everything works as expected.
Maybe I am missing something obvious, but not being able to disable Turbo for the button feels like a bug to me.
Tested with:
Happy to provide more information or context if that would be helpful.
Thanks!
Rails 6.1.0 installed with rails new --skip-action-mailbox --skip-action-text --skip-active-storage --skip-spring --skip-sprockets
. Added gem "turbo-rails", "~> 0.5.1"
to the Gemfile and Followed the webpack installation guide.
Any time I call a turbo-stream helper I get:
Same happens in the models when calling:
class Link < ApplicationRecord
belongs_to :network
broadcasts_to ->(link) { [ link.network, :links ] }, inserts_by: :prepend, target: "links"
end
It seems some part of the setup is missing, but I can't figure out what yet.
Currently Turbo should be returning responses with layout: false , however I have seen that that if a controller has a defined layout method that the controller defined layout get used in the Turbo response.
eg.
class TestController < ActionController::Base
def index
end
end
Everything will work fine and application.html.erb layout will NOT be used in Turbo response
class TestController < ActionController::Base
layout "custom"
def index
end
end
custom.html.erb layout will be used for Turbo response and seems to take precendence.
Expectation is that turbo should never use layout in its response
Hi,
When doing:
<%= turbo_stream.replace "flash_messages" do %>
<div id="flash_messages">
<% flash.each do |message_type, message| %>
<div data-controller="flash-component--base" class="alert alert-<%= alert_class(message_type) %> alert-dismissible fade show" role="alert">
<%= message %>
<button
type="button"
class="btn-close"
aria-label="Close"
data-action="click->flash-component--base#close"></button>
</div>
<% end %>
</div>
<% end %>
Everything works as expected, but when I do:
<%= turbo_stream.append "flash_messages" do %>
<% flash.each do |message_type, message| %>
<div data-controller="flash-component--base" class="alert alert-<%= alert_class(message_type) %> alert-dismissible fade show" role="alert">
<%= message %>
<button
type="button"
class="btn-close"
aria-label="Close"
data-action="click->flash-component--base#close"></button>
</div>
<% end %>
<% end %>
I get the following javascript error Error: <turbo-stream action="append" target="flash_messages">: first child element must be a <template> element
.
If I then wrap it in a template tag, it adds it to the dom like:
<div id="flash_messages">
<template>
</template>
</div>
Now, if I use plain html tags and not the rails helpers like below, everything works as expected:
<turbo-stream action="append" target="flash_messages">
<template>
<% flash.each do |message_type, message| %>
<div data-controller="flash-component--base" class="alert alert-<%= alert_class(message_type) %> alert-dismissible fade show" role="alert">
<%= message %>
<button
type="button"
class="btn-close"
aria-label="Close"
data-action="click->flash-component--base#close"></button>
</div>
<% end %>
</template>
</turbo-stream>
I am using:
gem "turbo-rails", "~> 0.5.2"
"@hotwired/turbo-rails": "^7.0.0-beta.2"
After switching to production I was required to include Action Cable because this gem's app/channels/turbo/streams_channel.rb
depends on it.
I am not using streams at all, so I'm wondering if this dependency is avoidable?
Ran into this error while upgrading a Rails 6 app that uses TypeScript and Turbolinks to the new Turbo. Any ideas? No results on DefinitelyTyped yet.
ERROR in app/javascript/packs/application.ts:10:30
TS7016: Could not find a declaration file for module '@hotwired/turbo-rails'. '/myapp/node_modules/@hotwired/turbo-rails/app/assets/javascripts/turbo.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/hotwired__turbo-rails` if it exists or add a new declaration (.d.ts) file containing `declare module '@hotwired/turbo-rails';`
8 |
> 9 | import { Turbo, cable } from "@hotwired/turbo-rails";
If the application does not use the asset pipeline, the app will crash because of the following initializer :
initializer "turbo.assets" do
Rails.application.config.assets.precompile += %w( turbo )
end
undefined method `assets' for #Rails::Application::Configuration:0x00007fa70a4d6be8 (NoMethodError)
Happy to provide a pull request to fix this behaviour if you believe it should not crash in this case
Thanks for making this ! <3
I don't use ActionCable or ActiveJob in my application. Also, I don't need real-time updates via WebSocket with Turbo.
If I comment out require "active_job/railtie"
and require "action_cable/engine"
in my application.rb
, I will get the following error when eager loading.
=> Booting Puma
=> Rails 6.1.0 application starting in development
=> Run `bin/rails server --help` for more startup options
Exiting
/home/kazuki/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/turbo-rails-0.5.3/app/channels/turbo/streams_channel.rb:7:in `<main>': uninitialized constant ActionCable (NameError)
Did you mean? Rational
from /home/kazuki/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
from /home/kazuki/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
I would like ActiveJob and ActionCable to be loaded only when necessary.
Thanks!
Currently signed stream names never expire:
As these are access tokens that makes me a bit uneasy.
Is it required that they are long living?
If so maybe adding a small explanatory comment would be beneficial. If not I'm happy to provide a pull request adding expiration.
In installed by following the readme for an app using the asset pipeline (the install script adds <%= turbo_include_tags %>
in my head
element).
But because that helper adds the turbo script as a module, the Turbo object isn't added to the global scope (and I can't do Turbo.visit
programmatically). Am I missing something? What's the right way of accessing the Turbo
object?
This is a very specific edge case me and a coworker ran into.
What is the best practice for error handling when broadcasting a turbo stream partial that contains an error?
First off, the simple solution is just to remove errors from your partials. But in a controller, I can also use the following method to render a custom error template. (say maybe render a turbo-frame="_top" to replace the page with a 500 page).
rescue_from ActionView::Template::Error, with: :render_template_error
But in a model that reuses those partials and broadcasts them, when trying to broadcast the partial, the partial throws an error and I now want the page to show the 500 page. Is there a broadcast_to "mychannel", on_error: :render_template_error
? And if that is the case, does this start to mix controller logic with model logic? Part of me feels like we should be able to broadcast controller actions.
I'm trying to get started with turbo-rails
. I am attempting to create a small sample application and ran into a problem, I can't seem to get turbo_stream.remove
to actually remove an item from my html.
The key bits are below
I have the following in my index.html.erb
:
<div id="users">
<%= render @users %>
</div>
the user (_user.html.erb
) partial looks like this:
<%= turbo_frame_tag dom_id(user) do %>
<p data-controller="users">
<strong>Username:</strong>
<%= user.username %>
<input data-users-target="id" value="<%= user.id %>" type="hidden" >
<%= link_to 'Edit', edit_user_path(user) %> |
<%= link_to 'Delete', "#", data: { action: "click->users#destroy" } %>
</p>
<% end %>
Because turbo-rails
doesn't currently support data-method
, I have the following piece of code in my stimulus controller to handle the delete link:
destroy() {
const token = document.querySelector('[name=csrf-token]').content
fetch('/users/' + this.idTarget.value, {
method: 'DELETE',
headers: {
'X-Csrf-Token': token,
"Accept": "text/html; turbo-stream, text/html, application/xhtml+xml",
"Turbo-Frame": "users"
}
})
}
My destroy action looks like this:
def destroy
@user.destroy
respond_to do |format|
format.turbo_stream
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
and my destroy.turbo_stream.erb
looks like this
<%= turbo_stream.remove @user %>
I can see that the turbo_stream template gets rendered when the DELETE
call is made by looking at the rails server logs, but but the html is never updated, and I can't quite understand what I'm missing (or maybe this use case isn't supported).
Another curious bit is that if I look at the network tab, the request returns a 200 but the response body is blank for the call. If I follow the request through rack and rails middleware, I can see the body being set correctly, so I have no idea where it is getting dropped.
Should this work? Or have I missed something completely obvious?
Here is a link to the example app if that would be helpful: https://github.com/tgturner/diceroll
We have a relatively large Rails codebase that uses the slim templating language along with Turbolinks (including native Turbolinks wrappers for iOS and Android). In general, it has worked great for us for years! (Thanks!)
But when I upgraded to Turbo, all our links appeared to stop working: The URL would change, and the client would make the request to the server (per browser console), and the server would render a response (per the Rails logs), but the DOM would never be updated with the content rendered by the server.
After a lot of trial and error, I finally figured out why: Our view files are generally named file_name.slim
rather than file_name.html.slim
. There was one link I could find that did work, and it happened to be one of the few files that included the .html
extension in its name.
Using this naming convention for our view files hasn't caused us issues before, so it's technically a regression from Turbolinks 5. I'm not sure if this is a common pattern that could affect lots of people, or if we're the only app doing it and we've been doing it wrong for years.
I figured it was worth posting here to both clarify our upgrade path (should we bite the bullet and do a massive file rename, or will this be treated as a bug to be fixed?) and to save others time if they encounter the same issue.
When adding turbo-rails to my already existing Rails 6 application (via webpacker, following the steps of the Readme), I get the following JS errors in the console:
Uncaught Error: Module parse failed: Unexpected token (2:9)
File was processed with these loaders:
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| import "./cable_stream_source_element";
> export * as Turbo from "@hotwired/turbo";
| export * as cable from "./cable";
at Object../node_modules/@hotwired/turbo-rails/app/javascript/turbo/index.js (application.js:2)
at __webpack_require__ (bootstrap:19)
at Module../app/webpacker/packs/application.js (application.js:1)
at __webpack_require__ (bootstrap:19)
at bootstrap:83
at bootstrap:83
I am quite helpless on what to do with those errors and if they are specific to my application or some general problem within the turbo package.
rails 6.1.0
turbo-rails 0.5.2
I create a minimal example in https://github.com/chloerei/turbo-stream-partial-example
When respond with:
<%= turbo_stream.append 'messages' do %>
<%= render partial: 'message', formats: [:html] %>
<% end %>
Everything is ok.
when respond with:
<%= turbo_stream.append 'messages' do %>
<%= render partial: 'message' %>
<% end %>
Get error:
ActionView::Template::Error (Missing partial home/_message, application/_message with {:locale=>[:en], :formats=>[:turbo_stream], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
* "/app/turbo-stream-partial-example/app/views"
* "/usr/local/bundle/gems/actiontext-6.1.0/app/views"
* "/usr/local/bundle/gems/actionmailbox-6.1.0/app/views"
):
1: <%= turbo_stream.append 'messages' do %>
2: <%= render partial: 'message' %>
3: <% end %>
Hi.
I'm trying to send a local variable to my partial when a message creation commit was triggered
broadcasts_to ->(message) { :messages }
after_create_commit :create_messages_view
private
def create_messages_view
broadcast_append_to self, partial: 'messages/message', locals: { cname: "test" }
end
But the return is:
[ActiveJob] Enqueued Turbo::Streams::ActionBroadcastJob (Job ID: 2fb92542-1e4e-4930-a410-d5c1f30a3fcc) to Async(default) with arguments: "messages", {:action=>:append, :target=>"messages", :locals=>{:message=>#<GlobalID:0x0000000008ab7a18 @uri=#<URI::GID gid://plezorchat/Message/26c4d6d0-c73e-4c8d-9267-e3d4637adef2>>}, :partial=>"messages/message"}
The local variable cname
does not reach the partial
Seems like this.subscription
is a promise and not the actual subscription at this point.
Error happens when navigating using the Back
link in the chat demo app. https://github.com/hotwired/hotwire-rails-demo-chat/blob/main/app/views/rooms/show.html.erb#L10
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.