user17914516
user17914516

Reputation: 169

rails turbo_stream is not working on a rails 7 application

I am trying to submit a form and return a turbo_stream on a rails 7.0 application. In my form I have the following.

 <%= form_with url: "/request_trial", method: :post, format: :turbo_stream do |form| %>
  <%= form.label :name, I18n.t('marketing.form.name'), class: 'form-label required' %>
  <%= form.text_field :name, class:"form-control", required: true %>

  <%= form.submit I18n.t('marketing.form.send'), class: 'btn btn-trial'  %>
<% end %>

In my controller I have the following

respond_to do |format|
  format.turbo_stream do |format|
    render turbo_stream: turbo_stream.replace(:'marketing-request-trial-form',
                                              partial: 'marketing/request_trial')
  end
end

This gives me an error ActionController::UnknownFormat

Although I have a format specify in my form, it seems that format is html when I submit the form.

I can see where this is coming from, on my request headers I have the following

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

I need to add on the request header the text/vnd.turbo-stream.html type, how can I do that?

Upvotes: 3

Views: 6779

Answers (2)

Yi Feng Xie
Yi Feng Xie

Reputation: 5017

The reason you got ActionController::UnknownFormat exception is that you only respond turbo_stream format, but the actual format is HTML(You didn't pass the correct format).

Solution 1

format: :turbo_stream is assumed to be passed as an argument of URL helpers rather than form helpers. For example:

some_url_helper_path(format: :turbo_stream)

In your literal URL case should be:

<%= form_with url: "/request_trial.turbo_stream", method: :post do |form| %>

Solution 2

Solution 1 can make controller respond turbo_stream correctly. But due to the bug, you might see turbo_stream as plain text instead of replacing views. Before a new version of Turbo js release, you can add a hidden field to forms manually:

<input type="hidden" name="format" value="turbo_stream">

Upvotes: 1

KennetsuR
KennetsuR

Reputation: 788

  • you need emphasis the format type
format.turbo_stream do
   render turbo_stream: turbo_stream.replace(@article, partial: 'welcome/form')
end
class WelcomeController < ApplicationController

  def index
    @article = Article.first
  end

  def update_article
    @article = Article.find(article_params[:id])
    respond_to do |format|
      if @article.update(article_params)
        format.turbo_stream do
          render turbo_stream: turbo_stream.replace(@article, partial: 'welcome/form')
        end
      end

    end
  end

  def article_params
    params.require(:article).permit(:id,:title, :body)
  end
end
  • index.html.erb
<h1>Welcome ! This is a tutorial about Rails forms</h1>
<%= turbo_frame_tag dom_id(@article) do %>
  <%= form_with  model: @article, url: update_article_path, method: :post, format: :turbo_stream do |form| %>
    <%= form.text_field :id %>
    <%= form.text_field :title %>
    <%= form.text_field :body %>
    <%= form.submit "Update" %>
  <% end %>
<% end %>
  • _form.html.erb
<%= turbo_frame_tag dom_id(@article) do %>
  <h1>New Book</h1>
  <div class="card card-body">
    <label>title</label>
    <input value="<%= @article.title %>">
  </div>
<% end %>
  • schema.rb
ActiveRecord::Schema[7.0].define(version: 2022_02_16_084944) do
  create_table "articles", force: :cascade do |t|
    t.string "title"
    t.text "body"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end

Upvotes: 3

Related Questions