Hello everyone. I just joined this community and this is my first post.
I’ve been following several Hotwire tutorials and have built some prototypes with the technology. I’ve been impressed with how easy it is to get SPA-like responsiveness with much less complexity compared to JS front end frameworks.
However, I’ve found that when I try to translate the code and process from my prototypes to my existing Rails project it simply never works. What’s worse is that I don’t know why.
I’ve tried to write some tracer code with the following general process:
Include the Hotwire gem
Install Hotwire via terminal command
Include broadcasts from the relevant model
Apply a turbo_stream_from tag as a listener at the view level
Include a turbo_frame_tag where you want the model data to be updated
This works reliably in my prototypes, but won’t work in my existing project. I’m suspecting it may be because my existing project isn’t using the latest version of Rails nor Ruby? (Upgrading has not proved easy either.) I am currently using Ruby version 2.7.1 and Rails version 6.0.2.
I know I should be offering up some of my project code, but I don’t even know where to begin. If anyone would be able to offer me some guidance I’d REALLY appreciate it. Thank you!
If it helps at all these are the kinds of terminal messages I’m getting when attempting to get Hotwire to autoupdate a list of model instances on an index page. It seems like the broadcast is working but my listener isn’t?
There are no errors popping up on the Chrome dev tools. It seems as though the broadcast from the model is working correctly. It also seems as though the turbo frame tags are setup correctly given that the model instances are present and appending. The problem is that additional instances of the model are only appending when I fully refresh the page. They are not appending automatically, as would be expected with a proper Hotwire setup. I have my the source HTML attached as a screenshot.
It’s really aggravating as this same general setup is working perfectly in my prototypes.
Both this app and my last prototype used webpacker, so I don’t believe that happens to be the issue. Perhaps it is a webpacker issue generally though? Any thoughts on how I’d best investigate that?
Thanks for taking the time to reply. I really appreciate it!
So I started preserving all the logs and then added a new story instance. There doesn’t appear to be any errors in the logs indicating a problem.
Once I refresh the page the new story instance appears as it would in a normal CRUD implementation. To answer your question more directly, the turbo_frame tags nested inside of the parent turbo_frame tag all render on refresh. For some reason they just don’t append dynamically/automatically (which is of course what I’m trying to achieve).
I don’t have any active job adapters but I do have a Redis server running in the background. Apparently this is needed to support Hotwire. I’ve attached screenshots of both the preserved logs and Redis.
In our app, because we’re using strict script_src and style_src settings, to inject JS that comes after the initial page load, we added:
# config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy_nonce_generator = ->(request) do
request.env["HTTP_X_TURBOLINKS_NONCE"].presence || SecureRandom.base64(16)
end
I wanted to circle back to this post to report that I didn’t find a solution. This is despite spending over a week’s worth of full-time hours trying to debug this problem.
In the end it was just faster and easier to start a new repo with the latest version of Ruby, Rails, and all of the gems. I proceeded to simply copy and paste as much code as I could into the new repo. Beyond that, I retraced my steps with my terminal commands and basically created a clone of the original app.
Lo and behold, it works.
The new app uses Ruby version 3.0.1 and Rails version 6.1.3.2. The old iteration of the app (the one that isn’t working) runs on Ruby version 2.7.1 and Rails version 6.0.2.2.
Thank you to everyone who reached out to try and help me in this matter.