skip to Main Content

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


  1. 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.

    format.turbo_stream { turbo_stream.replace/append/prepend(:div_tag_identifer, "<p> Some html content you want to show </p>")
    

    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, or turbo_stream.append("some/partiall", post: @post) for a creation.

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search