flop icon indicating copy to clipboard operation
flop copied to clipboard

implement Flop.Adapter behaviour for `Flop.List`

Open woylie opened this issue 1 year ago • 4 comments

woylie avatar Jul 15 '23 23:07 woylie

I’m new to flop and I would like to tackle this issue! In my application case I have the following situation: I do have my ecto models that map to database structures, however when it comes to the web interface I map/adapt these ecto models to embedded schemas that represent the “real data” that users care about.

I would like to use Flop but it is currently very based on ecto models/schemas. One of my example would be:

defmodule MyApp.Models.Post do

  # … ecto related imports

  schema “posts” do
    field :likes_count, :integer
    field :meta, :map
    belongs_to :user, User
  end
end

defmodule MyApp.Schemas.Post do

  embedded_schema do
    field :likes, :integer
    field :title, :string
    field :subtitle, :string
    field :content, :string
    field :user, :string
  end
end

defmodule MyApp.PostAdapter do
  def internal_to_external(%Model{} = model) :: Schema.t do
    %Schema{
      likes: model.likes_count,
      title: model.meta.title
      subtitle: model.meta.subtitle
      content: model.meta.content
      user: model.user.id
    }
  end
end

An then use the MyApp.Schemas.Post on the web interface (currently Live View).

As I didn’t use flop yet and I’m very new to the code base, do you could give me some initial directions?

zoedsoupe avatar Sep 09 '23 19:09 zoedsoupe

Hi @zoedsoupe, thank you, but this task is already on my table. This feature is also not related to your problem. What you probably want here is to derive the Flop.Schema protocol for MyApp.Models.Post. And when you make the query, you only need to convert the results into the external representation.

case Flop.validate_and_run(MyApp.Models.Post, %Flop{}, for: MyApp.Models.Post) do
  {:ok, {posts, meta}} -> {:ok, {MyApp.PostAdapter.internal_to_external(posts), meta}
  {:error, meta} -> {:error, meta}
end

woylie avatar Sep 09 '23 23:09 woylie

ok, that’s fine! but I don’t agree with your answer. I need to apply filtering and sorting for the MyApp.Schemas.Post not for the MyApp.Models.Post. I do want to render a data table with flop_phoenix for the schema. Maybe I didn’t explain very well.

My current setup is a fullstack app with phoenix Live View, where I have those “models”, that are what I save on database and these “schemas”, that are what users can se and interact with.

So in a index page for “Post”, that renders a table/data-table, will have for it source a list of MyApp.Schemas.Post. The source for filtering and sorting would be a list of MyApp.Schemas.Post, so deriving Flop directly on the model schema will not have the desired result, am I right?

zoedsoupe avatar Sep 11 '23 01:09 zoedsoupe

Normally you still want to do the filtering in the database, and not fetch all entries from the database and then filter on the server side. In that case, it doesn't matter which schema you use to render the UI, the filter configuration can still live in the Ecto schema for the database. If you want the filters to use the same naming as the presentation layer, you would need to rename them the same way you convert the filters.

If your tables are small, you might get away with filtering on the server-side. If you are sure you want to do that, you would need for this feature to be ready, or do some manual filter application in the meantime.

woylie avatar Sep 11 '23 02:09 woylie