@@ -6,6 +6,10 @@ defmodule Schemecto do
66 @ doc """
77 Creates a new schemaless changeset with the given field definitions.
88
9+ If parameters are given, they are cast into the changeset according
10+ to fields. Parameters are a keyword list, a map of string or atom keys,
11+ or nil.
12+
913 ## Parameters
1014
1115 * `fields` - List of field definitions. Each field is a map with:
@@ -23,12 +27,19 @@ defmodule Schemecto do
2327 %{name: :age, type: :integer, default: 0, description: "Age in years"}
2428 ]
2529
26- changeset = Schemecto.new(fields)
27- changeset = Ecto.Changeset.cast(changeset, %{name: "John", age: 30}, [:name, :age] )
30+ params = %{"name" => "John", "age" => 30}
31+ changeset = Schemecto.new(fields, params )
2832
2933 """
30- def new ( fields ) when is_list ( fields ) do
31- build_changeset ( fields )
34+ def new ( fields , params \\ % { } )
35+ when is_list ( fields ) and ( is_list ( params ) or is_map ( params ) or params == nil ) do
36+ changeset = build_changeset ( fields )
37+
38+ if params == [ ] or params == % { } or params == nil do
39+ changeset
40+ else
41+ Ecto.Changeset . cast ( changeset , params , Map . keys ( changeset . types ) )
42+ end
3243 end
3344
3445 @ doc """
@@ -38,14 +49,13 @@ defmodule Schemecto do
3849
3950 * `fields` - List of field definitions for the nested changeset
4051 * `opts` - Keyword list of options:
41- * `:with` - A 2 -arity function that receives a changeset and params,
42- and returns a validated changeset (required)
52+ * `:with` - A 1 -arity function that receives a changeset
53+ with the parameters already cast into them (if any) (required)
4354
4455 ## Examples
4556
46- def validate_address(changeset, params ) do
57+ def validate_address(changeset) do
4758 changeset
48- |> Ecto.Changeset.cast(params, [:street, :city, :zip])
4959 |> Ecto.Changeset.validate_required([:street, :city])
5060 end
5161
@@ -58,21 +68,19 @@ defmodule Schemecto do
5868 %{name: :city, type: :string},
5969 %{name: :zip, type: :string}
6070 ],
61- with: &validate_address/2
71+ with: &validate_address/1
6272 )}
6373 ]
6474
65- changeset =
66- Schemecto.new(fields)
67- |> Ecto.Changeset.cast(params, [:name, :email, :address])
75+ changeset = Schemecto.new(fields, params)
6876
6977 """
7078 def one ( fields , opts ) when is_list ( fields ) and is_list ( opts ) do
7179 function = Keyword . fetch! ( opts , :with )
7280
73- if not is_function ( function , 2 ) do
81+ if not is_function ( function , 1 ) do
7482 raise ArgumentError ,
75- "expected :with option to be a 2 -arity function, got: #{ inspect ( function ) } "
83+ "expected :with option to be a 1 -arity function, got: #{ inspect ( function ) } "
7684 end
7785
7886 Ecto.ParameterizedType . init ( Schemecto.One , % {
@@ -93,9 +101,8 @@ defmodule Schemecto do
93101
94102 ## Examples
95103
96- def validate_tag(changeset, params ) do
104+ def validate_tag(changeset) do
97105 changeset
98- |> Ecto.Changeset.cast(params, [:name, :color])
99106 |> Ecto.Changeset.validate_required([:name])
100107 end
101108
@@ -106,21 +113,19 @@ defmodule Schemecto do
106113 %{name: :name, type: :string},
107114 %{name: :color, type: :string}
108115 ],
109- with: &validate_tag/2
116+ with: &validate_tag/1
110117 )}
111118 ]
112119
113- changeset =
114- Schemecto.new(fields)
115- |> Ecto.Changeset.cast(params, [:title, :tags])
120+ changeset = Schemecto.new(fields, params)
116121
117122 """
118123 def many ( fields , opts ) when is_list ( fields ) and is_list ( opts ) do
119124 function = Keyword . fetch! ( opts , :with )
120125
121- if not is_function ( function , 2 ) do
126+ if not is_function ( function , 1 ) do
122127 raise ArgumentError ,
123- "expected :with option to be a 2 -arity function, got: #{ inspect ( function ) } "
128+ "expected :with option to be a 1 -arity function, got: #{ inspect ( function ) } "
124129 end
125130
126131 Ecto.ParameterizedType . init ( Schemecto.Many , % {
@@ -250,18 +255,13 @@ defmodule Schemecto do
250255 end
251256
252257 defp type_to_json_schema ( { :parameterized , { Schemecto.One , % { changeset: changeset , with: fun } } } ) do
253- changeset
254- |> fun . ( % { } )
255- |> to_json_schema ( )
258+ changeset |> fun . ( ) |> to_json_schema ( )
256259 end
257260
258261 defp type_to_json_schema ( { :parameterized , { Schemecto.Many , % { changeset: changeset , with: fun } } } ) do
259262 % {
260263 "type" => "array" ,
261- "items" =>
262- changeset
263- |> fun . ( % { } )
264- |> to_json_schema ( )
264+ "items" => changeset |> fun . ( ) |> to_json_schema ( )
265265 }
266266 end
267267
0 commit comments