im familiar with ROR and i want to use new Hotwire-Rails in my project. I’t is fine when i create posts. But when i updating/deleting posts nothing happened at the page. Can you please tell me where im doing wrong?
And finally i want make a sound when new post created how can i do that?
Thank you for your answers.
my "Gemfile"
gem 'redis', '~> 4.0'
gem 'hotwire-rails', '~> 0.1.3'
Application.js
require("@rails/ujs").start()
require("@rails/activestorage").start()
require("channels")
Application.html.erb
<body>
<%= turbo_include_tags %>
<%= yield %>
</body>
Post.rb
after_create_commit { broadcast_prepend_to "posts" }
after_update_commit { broadcast_replace_to "posts" }
after_destroy_commit { broadcast_remove_to "posts" }
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: %i[ show edit update destroy ]
# GET /posts or /posts.json
def index
@posts = Post.all
end
# GET /posts/1 or /posts/1.json
def show
end
# GET /posts/new
def new
@post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts or /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, status: :unprocessable_entity }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1 or /posts/1.json
def update
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to @post, notice: "Post was successfully updated." }
format.json { render :show, status: :ok, location: @post }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1 or /posts/1.json
def destroy
@post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: "Post was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:title, :body)
end
end
posts/index.html.erb
<%= turbo_stream_from "posts" %>
<%= turbo_frame_tag "posts" do %>
<%= render @posts %>
<% end %>
posts/_post.html.erb
<%= post.title %>:
<%= post.body %>
<%= link_to 'Edit', edit_post_path(post) %> |
<%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %> <br>
2
Answers
You’re missing handlers for the
turbo_stream
format in your controllers. If you want hotwire updates, you must add a handler like this to your update and destroy methods.Essentially, the controller method must render a Turbo response which includes the change you wish to see on the page. It might be
turbo_stream.replace(:some_div_id, "some/partial", post: @post)
for an update, orturbo_stream.append("some/partiall", post: @post)
for a creation.Yes it looks like this would try to redirect so you would miss the broadcast that got sent the page you need to put something in to stop the redirect which would could be a turbo_stream response instead or change the html response to render head :ok