Skip to content

Commit ee1b56b

Browse files
committed
use turbo streams for forms
1 parent 8db7510 commit ee1b56b

File tree

12 files changed

+84
-31
lines changed

12 files changed

+84
-31
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,5 @@
3838
!/app/assets/builds/.keep
3939

4040
/node_modules
41+
42+
TODO.txt

NOTES.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Rule 1: When clicking on a link within a Turbo Frame, Turbo expects a frame of the same id on the target page. It will then replace the Frame's content on the source page with the Frame's content on the target page.
2+
3+
Rule 2: When clicking on a link within a Turbo Frame, if there is no Turbo Frame with the same id on the target page, the frame disappears, and the error Response has no matching <turbo-frame id="name_of_the_frame"> element is logged in the console.
4+
5+
Rules 3: A link can target another frame than the one it is directly nested in thanks to the data-turbo-frame data attribute.
6+
7+
There is a special frame called `_top` that represents the whole page. It's not really a Turbo Frame, but it behaves almost like one, so we will make this approximation for our mental model.
8+
9+
10+
TURBO STREAM
11+
Note: As of writing this chapter, the turbo_stream helper responds to the following methods, so that it can perform the following actions:
12+
13+
# Remove a Turbo Frame
14+
turbo_stream.remove
15+
16+
# Insert a Turbo Frame at the beginning/end of a list
17+
turbo_stream.append
18+
turbo_stream.prepend
19+
20+
# Insert a Turbo Frame before/after another Turbo Frame
21+
turbo_stream.before
22+
turbo_stream.after
23+
24+
# Replace or update the content of a Turbo Frame
25+
turbo_stream.update
26+
turbo_stream.replace
27+
28+
When our user clicks on the "Cancel" link for the new quote form:
29+
30+
The link is within a Turbo Frame of id new_quote, so Turbo will only replace the content of this frame
31+
The link navigates to the Quotes#index page that contains an empty Turbo Frame with id new_quote
32+
Turbo replaces the content of the new_quote frame with the empty content, so the form disappears
33+
When our user clicks on the "Cancel" link for the edit quote form:
34+
35+
The link is within a Turbo Frame of id dom_id(quote), so Turbo will only replace the content of this frame
36+
The link navigates to the Quotes#index page that contains a Turbo Frame with id dom_id(quote) that contains the HTML for this quote
37+
Turbo replaces the content of the dom_id(quote) Frame containing the form with the HTML for this quote

app/controllers/quotes_controller.rb

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class QuotesController < ApplicationController
22
before_action :set_quote, only: [:show, :edit, :update, :destroy]
33

44
def index
5-
@quotes = Quote.all.order(updated_at: :asc)
5+
@quotes = Quote.desc_id_ordered
66
end
77

88
def show
@@ -16,10 +16,13 @@ def create
1616
@quote = Quote.new(quote_params)
1717

1818
if @quote.save
19-
redirect_to quotes_url, notice: "Quote was successfully created."
20-
else
21-
render :new, status: :unprocessable_entity
19+
respond_to do |format|
20+
format.html { redirect_to quotes_path, notice: "Quote was successfully created." }
21+
format.turbo_stream
2222
end
23+
else
24+
render :new, status: :unprocessable_entity
25+
end
2326
end
2427

2528
def edit
@@ -35,7 +38,10 @@ def update
3538

3639
def destroy
3740
@quote.destroy
38-
redirect_to quotes_path, notice: "Quote was successfully destroyed."
41+
respond_to do |format|
42+
format.html { redirect_to quotes_path, notice: "Quote was successfully destroyed." }
43+
format.turbo_stream
44+
end
3945
end
4046

4147
private

app/models/quote.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
class Quote < ApplicationRecord
22
validates :name, presence: true
3+
4+
scope :desc_id_ordered, -> { order(id: :desc) }
35
end

app/views/quotes/_form.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ COMMENT
3030
<% end %>
3131

3232
<%= f.input :name, input_html: { autofocus: true } %>
33+
<%= link_to "Cancel", quotes_path, class: "btn btn--light" %>
3334
<%= f.submit class: "btn btn--secondary" %>
3435
<% end %>

app/views/quotes/_quote.html.erb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@
77
COMMENT
88
%>
99

10-
<div class="quote">
11-
<%= link_to quote.name, quote_path(quote) %>
12-
<div class="quote__actions">
13-
<%= button_to "Delete",
14-
quote_path(quote),
15-
method: :delete,
10+
<%= turbo_frame_tag quote do %>
11+
<div class="quote">
12+
<%= link_to quote.name,
13+
quote_path(quote),
14+
data: { turbo_frame: "_top" } %>
15+
<div class="quote__actions">
16+
<%= button_to "Delete",
17+
quote_path(quote),
18+
method: :delete,
19+
class: "btn btn--light" %>
20+
<%= link_to "Edit",
21+
edit_quote_path(quote),
1622
class: "btn btn--light" %>
17-
<%= link_to "Edit",
18-
edit_quote_path(quote),
19-
class: "btn btn--light" %>
23+
</div>
2024
</div>
21-
</div>
25+
<% end %>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<%= turbo_stream.prepend "quotes", @quote %>
2+
<%= turbo_stream.update Quote.new, "" %>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<%= turbo_stream.remove @quote %>

app/views/quotes/edit.html.erb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ COMMENT
2222
<h1>Edit quote</h1>
2323
</div>
2424

25-
<%= render "form", quote: @quote %>
25+
<%= turbo_frame_tag @quote do %>
26+
<%= render "form", quote: @quote %>
27+
<% end %>
2628
</main>

app/views/quotes/index.html.erb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ COMMENT
2424
<h1>Quotes</h1>
2525
<%= link_to "New quote",
2626
new_quote_path,
27-
class: "btn btn--primary" %>
27+
class: "btn btn--primary",
28+
data: { turbo_frame: dom_id(Quote.new) } %>
2829
</div>
2930

30-
<%= render @quotes %>
31+
<%= turbo_frame_tag Quote.new %>
32+
<%= turbo_frame_tag "quotes" do %>
33+
<%= render @quotes %>
34+
<% end %>
3135
</main>

0 commit comments

Comments
 (0)