From c89b123a6cef5be5ad463c7f6d7212e2d7a46cf3 Mon Sep 17 00:00:00 2001 From: jho406 Date: Sat, 22 Jun 2024 21:09:06 -0400 Subject: [PATCH] Simplify the setting of pageKey (#73) This commit makes Superglue a bit smarter. Previously, content-location was used to specify the pageKey for 200s from non-get requests, but this was too cumbersome as the most common use case was setting the URL to be the referrer of the non-get request upon 200. This uses that as the default logic but still accepts content-location if we want to explicitly override from the server, which is unlikely. Additionally I simplified the logic. We always want to use the response's URL unless in the case mentioned above. Existing tests pass. --- docs/rails.md | 48 ++++++++----------- superglue/lib/action_creators/requests.ts | 18 +++---- .../rails/templates/controller.rb.tt | 2 - 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/docs/rails.md b/docs/rails.md index 571805c2..afcb15a2 100644 --- a/docs/rails.md +++ b/docs/rails.md @@ -1,33 +1,5 @@ # Rails -## Setting the content location - -On non-GET `visit`s, Superglue uses the response's `content-location` to create -the key used to store your props. - -This is because when you render in a `create` or `update`, the returned -response does not necessarily reflect the url the user should see. - -For example, when the user is on `posts/new` and they make a POST request to -`posts/`, we may decide to render `posts/new` for any errors you'd like to -show. - -It is recommended that you set this header in your `create` and `update` -methods. If you used the generators, this is done for you. - -```ruby -def create - @post = Post.new(post_params) - - if @post.save - redirect_to @post, notice: 'Post was successfully created.' - else - response.set_header("content-location", new_post_path) - render :new - end -end -``` - ## Rails Flash The installation generator will add a `flash.js` slice to `app/javascript/slices` @@ -66,3 +38,23 @@ def create redirect_back_with_props_at fallback_url: '/' end ``` + +## Setting the content location + +You can override the URL Superglue uses to display on the address bar and +store your response directly from the server using `content-location`. This +is optional. For example: + +```ruby +def create + @post = Post.new(post_params) + + if @post.save + redirect_to @post, notice: 'Post was successfully created.' + else + response.set_header("content-location", new_post_path) + render :new + end +end +``` + diff --git a/superglue/lib/action_creators/requests.ts b/superglue/lib/action_creators/requests.ts index 13d8ad4a..4990232e 100644 --- a/superglue/lib/action_creators/requests.ts +++ b/superglue/lib/action_creators/requests.ts @@ -206,13 +206,14 @@ export function visit( rsp, fetchArgs, } + const isGet = fetchArgs[1].method === 'GET' meta.suggestedAction = 'push' - if (!rsp.redirected && fetchArgs[1].method != 'GET') { + if (!rsp.redirected && !isGet) { meta.suggestedAction = 'replace' } - if (revisit && fetchArgs[1].method == 'GET') { + if (revisit && isGet) { if (rsp.redirected) { meta.suggestedAction = 'replace' } else { @@ -220,16 +221,15 @@ export function visit( } } - if (method !== 'GET') { - const contentLocation = rsp.headers.get('content-location') + pageKey = urlToPageKey(rsp.url) - if (contentLocation) { - pageKey = urlToPageKey(contentLocation) - } + if (!isGet && !rsp.redirected) { + pageKey = currentPageKey } - if (rsp.redirected) { - pageKey = urlToPageKey(rsp.url) + const contentLocation = rsp.headers.get('content-location') + if (contentLocation) { + pageKey = urlToPageKey(contentLocation) } const page = beforeSave(pages[pageKey], json) diff --git a/superglue_rails/lib/generators/rails/templates/controller.rb.tt b/superglue_rails/lib/generators/rails/templates/controller.rb.tt index f3999bb9..42b9e342 100644 --- a/superglue_rails/lib/generators/rails/templates/controller.rb.tt +++ b/superglue_rails/lib/generators/rails/templates/controller.rb.tt @@ -31,7 +31,6 @@ class <%= controller_class_name %>Controller < ApplicationController if @<%= orm_instance.save %> redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %> else - response.set_header("content-location", new_<%= singular_table_name %>_path) render :new end end @@ -41,7 +40,6 @@ class <%= controller_class_name %>Controller < ApplicationController if @<%= orm_instance.update("#{singular_table_name}_params") %> redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %> else - response.set_header("content-location", edit_<%= singular_table_name %>_path(@<%= singular_table_name %>)) render :edit end end