GithubHelp home page GithubHelp logo

Comments (7)

zachdaniel avatar zachdaniel commented on August 20, 2024 1

@sevenseacat feel free to reopen if you see more issues along these lines.

from ash_phoenix.

zachdaniel avatar zachdaniel commented on August 20, 2024

So after thinking about this a bit more, I think the actual answer here is for the data to come back from the action with the resulting relationship loaded, and already sorted. This would only work in some cases, specifically when the entire relationship needs to be loaded, or in cases where we are performing a create action and are creating related records. However, if you aren't in one of those cases, you almost certainly aren't expecting to save the form and then get records back in the same order anyway, because if you load the relationship you'll get more than you sent back. So the pattern would look something like this:

case Form.submit(form) do
  {:ok, result} ->
     assign_form(socket, result)
   {:error, form} ->
     assign(socket, :form, form)
end

...

defp assign_form(socket, thing_you_are_updating) do
  thing_you_are_updating
  |> Api.load!([relationship: :foo], lazy?: true) # the `lazy?: true` will keep anything that is already loaded, and the edited relationship will be loaded as a result of the action
  |> AshPhoenix.Form.for_update(...)
end

from ash_phoenix.

zachdaniel avatar zachdaniel commented on August 20, 2024

Actually...looks like we're already doing this in core :) @sevenseacat perhaps you could try using a lazy?: true load as illustrated above and see if that works for you?

from ash_phoenix.

sevenseacat avatar sevenseacat commented on August 20, 2024

Originally the reason I was reloading all of the data was because relationships weren't coming back on the record after update, meaning re-rendering the form was erroring - that doesn't seem to happen anymore which is good! I can remove that reloading-data loop entirely.

However, the data is still being returned by the action in a different order.

eg.

    dbg(AshPhoenix.Form.value(socket.assigns.element_form, :tool_specifications))
    dbg(params)

    case AshPhoenix.Form.submit(socket.assigns.element_form, params: params) do
      {:ok, updated_element} ->
        dbg(updated_element.tool_specifications)

gives:

AshPhoenix.Form.value(socket.assigns.element_form, :tool_specifications) #=> [
  %{
    "_form_type" => "update",
    "id" => "abdab2a1-a221-43fe-be50-1add1a40cf8f",
    "quantity" => "1431",
    "specification_id" => "ea9544d9-5d5a-4014-9a59-335719bcd2ea",
  },
  %{
    "_form_type" => "update",
    "id" => "a3bc5d69-b683-4e42-83df-9a24eb9a2881",
    "quantity" => "21",
    "specification_id" => "022e2e06-fbe9-41d9-9860-4d67ca8a73c0",
  }
]

params #=> %{
  # other stuff
  "tool_specifications" => %{
    "0" => %{
      "_form_type" => "update",
      "_touched" => "_form_type,id,quantity,specification_id",
      "id" => "abdab2a1-a221-43fe-be50-1add1a40cf8f",
      "quantity" => "1431",
      "specification_id" => "ea9544d9-5d5a-4014-9a59-335719bcd2ea",
    },
    "1" => %{
      "_form_type" => "update",
      "_touched" => "_form_type,id,quantity,specification_id",
      "id" => "a3bc5d69-b683-4e42-83df-9a24eb9a2881",
      "quantity" => "21",
      "specification_id" => "022e2e06-fbe9-41d9-9860-4d67ca8a73c0",
    }
  }
}

updated_element.tool_specifications #=> [
  #MyApp.Element.ToolSpecification<
    specification: #MyApp.Tool.Specification<>,
    __meta__: #Ecto.Schema.Metadata<:loaded, "element_tool_specifications">,
    id: "a3bc5d69-b683-4e42-83df-9a24eb9a2881",
    quantity: 21,
    inserted_at: ~U[2022-10-17 06:16:24.635005Z],
    updated_at: ~U[2022-10-19 01:12:37.432723Z],
    element_id: "a8316188-2fe2-4ddb-a9b4-e02cb209bbac",
    specification_id: "022e2e06-fbe9-41d9-9860-4d67ca8a73c0",
    aggregates: %{},
    calculations: %{},
    __order__: nil,
    ...
  >,
  #MyApp.Element.ToolSpecification<
    specification: #MyApp.Tool.Specification<>,
    element: #Ash.NotLoaded<:relationship>,
    __meta__: #Ecto.Schema.Metadata<:loaded, "element_tool_specifications">,
    id: "abdab2a1-a221-43fe-be50-1add1a40cf8f",
    quantity: 1431,
    inserted_at: ~U[2022-10-17 05:53:26.206812Z],
    updated_at: ~U[2022-10-19 01:13:16.172939Z],
    element_id: "a8316188-2fe2-4ddb-a9b4-e02cb209bbac",
    specification_id: "ea9544d9-5d5a-4014-9a59-335719bcd2ea",
    aggregates: %{},
    calculations: %{},
    __order__: nil,
    ...
  >
]

from ash_phoenix.

zachdaniel avatar zachdaniel commented on August 20, 2024

Okay, yeah I can see that. I guess the current behavior just doesn't do the work to preserve order. I'll take a look in the morning.

from ash_phoenix.

zachdaniel avatar zachdaniel commented on August 20, 2024

I'm actually pretty sure its just reversing the inputs, because as we apply the inputs we do things like [result | relationship_value]. So I'll toss in an Enum.reverse in and I think we'll be good :)

from ash_phoenix.

zachdaniel avatar zachdaniel commented on August 20, 2024

Alright, so this should be fixed in ash main. Anyone else looking: if you are loading data after submitting a form, you will want to use lazy?: true so as not to potentially reorder the relationship after editing it.

from ash_phoenix.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.