Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: edit stop broken after dependency update #1031

Merged
merged 1 commit into from
Nov 1, 2024
Merged

Conversation

Whoops
Copy link
Collaborator

@Whoops Whoops commented Nov 1, 2024

Summary of changes

Asana Ticket: 🐛🏹 Fix Stop ID Validation in Stop Form

Reviewer Checklist

  • Meets ticket's acceptance criteria
  • Any new or changed functions have typespecs
  • Tests were added for any new functionality (don't just rely on Codecov)
  • This branch was deployed to the staging environment and is currently running with no unexpected increase in warnings, and no errors or crashes.

@@ -130,7 +129,7 @@ defmodule ArrowWeb.StopViewLive do
end

def handle_event("validate", %{"stop" => stop_params}, socket) do
form = Stops.change_stop(%Stop{}, stop_params) |> to_form(action: :validate)
form = Stops.change_stop(socket.assigns.stop, stop_params) |> to_form(action: :validate)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial bug happened because we use unsafe_validate_unique to ensure we don't duplicate stop_ids and with us always comparing to an empty %Stop{}, it always thought we changed the stop_id so ran the validation. Building our changeset against the original stop prevents that.

I'm unsure why the original code was OK with it.

@@ -103,14 +103,13 @@ defmodule ArrowWeb.StopViewLive do
def mount(_params, session, socket) do
logout_url = session["logout_url"]
form = to_form(Stops.change_stop(%Stop{}))
stops = Stops.list_stops()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stops was never used, so I removed it. It is unrelated to the issue at hand, so I can put it back if we'd rather be conservative.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's clear enough to me that it's unused, plus pulling in all of the stops probably adds a smidgen of slowness to the initial component mount, so I'm fine with removing it.

@@ -54,7 +54,7 @@ defmodule ArrowWeb.Router do
live("/stops/new", StopViewLive, :new)
live("/stops/:id/edit", StopViewLive, :edit)
get("/stops", StopController, :index)
post("/stops/:id", StopController, :update)
put("/stops/:id", StopController, :update)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm more than a little baffled as to why this is a PUT now when submitting the form. It makes sense from a REST perspective, but from an engineering one I haven't worked out what's changing the method on the form when we are doing an edit vs a create (create is still post, I tested)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tracked this down to the call to to_form generating a form structure with the method options: [method: "put"], when being called on a changeset based on an existing stop, and options: [method: "post"] when the changeset is based on an empty Stop, but best I can tell this is undocumented, and doesn't appear in the changelog.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I tracked this down. The behavior comes from phoenix_html, and it's been this way for a long time. The reason it was POST in the version of the code before is because while the form would initially be generated from the stop with and therefore have the method set to "put", the validate event when it fired was replacing the form with one based on a new stop (form = Stops.change_stop(%Stop{}, stop_params) |> to_form(action: :validate)), and so got replaced with a form with the method: "post". This new version continues to use the existing stop, so the form remains "put"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, that's another weird issue I ran into with the form that I had been wondering about!

@Whoops Whoops requested review from a team and lemald and removed request for a team November 1, 2024 18:48
Copy link
Member

@lemald lemald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - thanks for figuring this out, even if it's still a little mysterious exactly why it worked initially.

@Whoops Whoops merged commit f209720 into master Nov 1, 2024
76 checks passed
@Whoops Whoops deleted the wh-stops-validation branch November 1, 2024 19:23
@@ -122,7 +122,7 @@ defmodule ArrowWeb.StopLiveTest do
conn = follow_trigger_action(form, conn)
assert conn.method == "POST"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why this conn.method is still POST? 🤔

The test fails if you change it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants