All Projects → Adzz → Ecto_morph

Adzz / Ecto_morph

morph your Ecto capabilities into the s t r a t o s p h e r e !

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Ecto morph

Wallaby
Concurrent browser tests with elixir
Stars: ✭ 1,143 (+1487.5%)
Mutual labels:  ecto, phoenix
Elixir Boilerplate
⚗ The stable base upon which we build our Elixir projects at Mirego.
Stars: ✭ 627 (+770.83%)
Mutual labels:  ecto, elixir-phoenix
Paper trail
Track and record all the changes in your database with Ecto. Revert back to anytime in history.
Stars: ✭ 380 (+427.78%)
Mutual labels:  ecto, phoenix
Papercups
Open-source live customer chat
Stars: ✭ 4,554 (+6225%)
Mutual labels:  phoenix, elixir-phoenix
Elixirbooks
List of Elixir books
Stars: ✭ 1,021 (+1318.06%)
Mutual labels:  phoenix, elixir-phoenix
Phoenix slime
Phoenix Template Engine for Slime
Stars: ✭ 286 (+297.22%)
Mutual labels:  phoenix, elixir-phoenix
Kaffy
Powerfully simple admin package for phoenix applications
Stars: ✭ 617 (+756.94%)
Mutual labels:  ecto, phoenix
pryin
PryIn is an Application Performance Monitoring platform for your Elixir/Phoenix application.
Stars: ✭ 25 (-65.28%)
Mutual labels:  phoenix, elixir-phoenix
Query
Query adds tools to aid the use of Ecto in web settings.
Stars: ✭ 23 (-68.06%)
Mutual labels:  ecto, phoenix
Drab
Remote controlled frontend framework for Phoenix.
Stars: ✭ 833 (+1056.94%)
Mutual labels:  phoenix, elixir-phoenix
plug rails cookie session store
Rails compatible Plug session store
Stars: ✭ 93 (+29.17%)
Mutual labels:  phoenix, elixir-phoenix
Phoenix In Action
Code snippets and examples from the book Phoenix in Action from Manning and Geoffrey Lessel
Stars: ✭ 60 (-16.67%)
Mutual labels:  phoenix, elixir-phoenix
one plus n detector
Elixir library to help you detect 1+n queries in applications using Ecto
Stars: ✭ 20 (-72.22%)
Mutual labels:  phoenix, ecto
Machinery
State machine thin layer for structs (+ GUI for Phoenix apps)
Stars: ✭ 367 (+409.72%)
Mutual labels:  ecto, phoenix
ecto generator
Generate Ecto schemas from existing database in Phoenix - Elixir
Stars: ✭ 20 (-72.22%)
Mutual labels:  phoenix, ecto
Awesome Phoenix
🔥 Collection of awesome open-source apps made with Phoenix Framework
Stars: ✭ 481 (+568.06%)
Mutual labels:  phoenix, elixir-phoenix
pretty print formatter
Pretty Print Formatter for Elixir Logger module -- Colorize Ecto's SQL ouput 🖌️
Stars: ✭ 22 (-69.44%)
Mutual labels:  phoenix, ecto
mindwendel
Create a challenge. Ready? Brainstorm. mindwendel helps you to easily brainstorm and upvote ideas and thoughts within your team.
Stars: ✭ 22 (-69.44%)
Mutual labels:  phoenix, elixir-phoenix
Accent
The first developer-oriented translation tool. True asynchronous flow between translators and your team.
Stars: ✭ 721 (+901.39%)
Mutual labels:  ecto, elixir-phoenix
Phoenix Ecto Append Only Log Example
📝 A step-by-step example/tutorial showing how to build a Phoenix (Elixir) App where all data is immutable (append only). Precursor to Blockchain, IPFS or Solid!
Stars: ✭ 58 (-19.44%)
Mutual labels:  phoenix, elixir-phoenix

EctoMorph

EctoMorph morphs your Ecto capabilities into the s t r a t o s p h e r e !

Parse incoming data into custom structs, then validate it.

Usually you have to do something like this:

defmodule Embed do
  use Ecto.Schema

  embedded_schema do
    field(:bar, :string)
  end
end

defmodule Test do
  use Ecto.Schema

  embedded_schema do
    field(:thing, :string)
    embeds_one(:embed, Embed)
  end

Ecto.Changeset.cast(%Test{}, %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}, [:thing])
|> Ecto.Changeset.cast_embed(:embed)

Now we can do this:

data = %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
EctoMorph.cast_to_struct(data, Test)

# or
data = %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
EctoMorph.cast_to_struct(data, Test, [:thing, embed: [:bar]])

# The data can also be a struct so this would work:
data = %Test{thing: "foo", embed: %Embed{bar: "baz"}}
EctoMorph.cast_to_struct(data, Test, [:thing, embed: [:bar]])

# So would this:
data = %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
EctoMorph.cast_to_struct(data, %Test{}, [:thing, embed: [:bar]])

# Changes can even be a different struct, if it
# has overlapping keys they will be casted as expected:

defmoule OtherStruct do
  defstruct [:thing, :embed]
end

data = %OtherStruct{thing: "foo", embed: %{"bar"=> "baz"}}
EctoMorph.cast_to_struct(data, %Test{}, [:thing, embed: [:bar]])

Or something like this:

with {:ok, %{status: 200, body: body}} <- HTTPoison.get("mygreatapi.co.uk") do
  EctoMorph.cast_to_struct(Jason.decode!(body), User)
end

We can also whitelist fields to cast / update:

data = %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
EctoMorph.cast_to_struct(data, Test, [:thing])

data = %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
EctoMorph.cast_to_struct(data, Test, [:thing, embed: [:bar]])

Sometimes it makes sense to update a struct we have retrieved from the database with data from our response. We can do that like so:

def update(data) do
  # This will update the db struct with the data passed in, then update the db.
  MyRepo.get!(MySchema, 10)
  |> EctoMorph.update_struct(data)
  |> MyRepo.update!()
end

Validations

Often you'll want to do some validations, that's easy:

(
  %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
  |> EctoMorph.generate_changeset(Test, [:thing])
  |> Ecto.Changeset.validate_required([:thing])
  |> EctoMorph.into_struct()
)

# or
(
  %{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
  |> EctoMorph.generate_changeset(Test, [:thing])
  |> Ecto.Changeset.validate_change(...)
  |> Repo.insert!
)

Valiating Nested Changesets

Easily the coolest feature, say you have nested changesets via embeds or has_one/many, you can now specify a path to a changeset and specify a validation function for the changeset(s) at the end of that path. If your path ends at a list of changesets (because your model has a has_many relation for example), each of those changesets will be validated.

%{"thing" => "foo", "embed" => %{"bar"=> "baz"}}
|> EctoMorph.generate_changeset(Test)
|> EctoMorph.validate_nested_changeset([:embed], &MyEmbed.validate/1)

# or
json = %{
  "has_many" => [
    %{"steamed_hams" => [%{"pickles" => 1}, %{"pickles" => 2}]},
    %{"steamed_hams" => [%{"pickles" => 1}]},
    %{"steamed_hams" => [%{"pickles" => 4}, %{"pickles" => 5}]}
  ]
}

# Here each of the steamed_hams above will have their pickle count validated:

EctoMorph.generate_changeset(json, MySchema)
|> EctoMorph.validate_nested_changeset([:has_many, :steamed_hams], fn changeset ->
  Ecto.Changeset.validate_number(changeset, :pickles, greater_than: 3)
end)

Other abilities include creating a map from an ecto struct, dropping optional fields if you decide to:

EctoMorph.map_from_struct(%Test{})
%{foo: "bar", updated_at: ~N[2000-01-01 23:00:07], inserted_at: ~N[2000-01-01 23:00:07], id: 10}

EctoMorph.map_from_struct(%Test{}, [:exclude_timestamps])
%{foo: "bar", id: 10}

EctoMorph.map_from_struct(%Test{}, [:exclude_timestamps, :exclude_id])
%{foo: "bar"}

and being able to filter some data by the fields in the given schema:

defmodule Test do
  use Ecto.Schema

  embedded_schema do
    field(:random, :string)
  end
end

EctoMorph.filter_by_schema_fields(%{random: "data", more: "fields"}, Test)
%{random: "data"}

You can even deep filter:

defmodule OtherThing do
  use Ecto.Schema
  @primary_key false
  embedded_schema do
    field(:id, :integer)
  end
end

defmodule Test do
  use Ecto.Schema

  embedded_schema do
    field(:random, :string)
    embeds_one(:other_thing, OtherThing)
  end
end

data = %{
  random: "data",
  more: "fields",
  __meta__: "stuff",
  other_thing: %{id: 1, ignored: "field"}
}

EctoMorph.deep_filter_by_schema_fields(data, Test)
%{random: "data", other_thing: %{id: 1}}

Deep filtering will keep virtual fields, relations and through relations. That means you can use it to create a map of the struct fields without ecto metadata if you filter it by itself:

data = %Test{
  random: "data",
  more: "fields",
  __meta__: "stuff",
  other_thing: %OtherThing{id: 1, ignored: "field"}
}

EctoMorph.deep_filter_by_schema_fields(data, Test)
%{random: "data", other_thing: %{id: 1}}

Check out the docs for more examples and specifics

Installation

available in Hex, the package can be installed by adding ecto_morph to your list of dependencies in mix.exs:

def deps do
  [
    {:ecto_morph, "~> 0.1.23"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ecto_morph.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].