Giter Site home page Giter Site logo

williamthome / changeset Goto Github PK

View Code? Open in Web Editor NEW
5.0 1.0 1.0 112 KB

An OTP library to validate data based on Ecto changeset library (Elixir).

License: Apache License 2.0

Erlang 100.00%
changeset erlang erlang-library rebar3 validate validation-library

changeset's Introduction

changeset

An OTP library to validate data based on Ecto changeset library (Elixir).

Disclaimer

This is a WIP library. The code may change at any time without notice.

Example

Take this simple module:

-module(movie).

-export([changeset/1, changeset/2]).

-define(TYPES,     #{name => binary, starring => binary}).
-define(PERMITTED, maps:keys(?TYPES)).
-define(REQUIRED,  [name]).

changeset(Params) ->
    changeset(#{}, Params).

changeset(Data, Params) ->
    Changeset = changeset:cast({Data, ?TYPES}, Params, ?PERMITTED),
    changeset:pipe(Changeset, [
        changeset:validate_required(?REQUIRED)
        % More validators here, e.g.:
        % changeset:validate_change(name, fun(_Name) -> [] end)
        % changeset:validate_format(name, "^[A-Z]")
        % changeset:validate_member(starring, [<<"Mike">>, <<"Joe">>, <<"Robert">>])
        % changeset:validate_not_member(starring, [<<"Me">])
    ]).

Now running

rebar3 shell

we can type the following:

% The name is missing, the changeset will be invalid
1> movie:changeset(#{}).
{changeset,[],
           #{name => binary,starring => binary},
           [name],
           #{},#{},
           [{name,{<<"is required">>,#{validation => is_required}}}],
           [undefined,<<>>]}

% The name is not a binary, the changeset will be invalid
2> movie:changeset(#{name => foo}).
{changeset,[],
           #{name => binary,starring => binary},
           [name],
           #{},
           #{name => foo},
           [{name,{<<"must be a binary">>,#{validation => is_binary}}}],
           [undefined,<<>>]}

% The name is present and it's a binary, then the changeset will be valid
3> movie:changeset(#{name => <<"Erlang: The Movie">>}).
{changeset,[],
           #{name => binary,starring => binary},
           [name],
           #{},
           #{name => <<"Erlang: The Movie">>},
           [],
           [undefined,<<>>]}

% Get the valid changes
4> changeset:get_changes(v(3)).
#{name => <<"Erlang: The Movie">>}

Struct

Currently, this is the changeset record

-record(changeset,
    { fields       = []                :: [field()]
    , types        = #{}               :: #{field() := type()}
    , required     = []                :: [field()]
    , data         = #{}               :: #{field() => term()}
    , changes      = #{}               :: #{field() => term()}
    , errors       = []                :: [error()]
    , empty_values = [undefined, <<>>] :: nonempty_list()
    }).

and this are the available field types:

-type type() :: atom
              | binary
              | bitstring
              | boolean
              | float
              | function
              | {function, arity()}
              | integer
              | list
              | map
              | pid
              | port
              | record
              | {record, Name :: atom()}
              | {record, Name :: atom(), Size :: non_neg_integer()}
              | reference
              | tuple
              .

The types are auto validated by the cast function.

changeset's People

Contributors

fancycade avatar williamthome avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

fancycade

changeset's Issues

What is the difference of Data and Params ?, And what is fields and how to utilized fields

Hi @williamthome

  • What is the difference of Data and Params ?
  • What is fields[] and how to utilize it?
  • Why fields always empty list?
  • Why data always empty map?

Valid Input

{changeset,[],
           #{name => binary,starring => binary},
           [name],
           #{},
           #{name => <<"Erlang the movie">>},
           [],
           [undefined,<<>>]}

Invalid Input

{changeset,[],
           #{name => binary,starring => binary},
           [name],
           #{},#{},
           [{name,{<<"is required">>,#{validation => is_required}}}],
           [undefined,<<>>]}

Both Valid and Invalid input always returning empty list [] for fields parameter, and empty map #{} in data parameter.

Thank you ๐Ÿ™

changeset:pipe() not return all validation errors. Only return 1 validation error.

Hi @williamthome ,

I have following code

-module(model_user).
-export([changeset/1, changeset/2]).

-define(TYPES, #{
    id => binary,
    username => binary,
    userpassword => binary,
    role => binary,
    created_at => tuple
}).
-define(PERMITTED_ALL_ATTR, maps:keys(?TYPES)).
-define(REQUIRED_ALL_ATTR, maps:keys(?TYPES)).

changeset(Params) ->
    changeset(#{}, Params).

changeset(Data, Params) ->
    Changeset = changeset:cast({Data, ?TYPES}, Params, ?PERMITTED_ALL_ATTR),
    changeset:pipe(Changeset, [
        changeset:validate_required(?REQUIRED_ALL_ATTR),
        changeset:validate_member(role, [<<"ADMIN">>, <<"MITRA">>])
    ]).

Then when I do / execute the validation: model_user:changeset(#{}).
I only get 1 validation error: [{id,{<<"is required">>,#{validation => is_required}}}]
My expectation I get 5 validation error in total.

But I only get the following:

{changeset,[],
           #{id => binary,role => binary,username => binary,
             userpassword => binary,created_at => tuple},
           [id,role,username,userpassword,created_at],
           #{},#{},
           [{id,{<<"is required">>,#{validation => is_required}}}],  %% I only get 1 validation error. How to get all validation errors?
           [undefined,<<>>]}

Thank you ๐Ÿ™

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.