@@ -2,6 +2,8 @@ defmodule Kaffy.ResourceAdmin do
2
2
alias Kaffy.ResourceSchema
3
3
alias Kaffy.Utils
4
4
5
+ @ default_id_separator ":"
6
+
5
7
@ moduledoc """
6
8
ResourceAdmin modules should be created for every schema you want to customize/configure in Kaffy.
7
9
@@ -148,7 +150,7 @@ defmodule Kaffy.ResourceAdmin do
148
150
@ doc """
149
151
`ordering/1` takes a schema and returns how the entries should be ordered.
150
152
151
- If `ordering/1` is not defined, Kaffy will return `[desc: :id]` .
153
+ If `ordering/1` is not defined, Kaffy will return `[desc: primary_key]`, or the first field of the primary key, if it's a composite .
152
154
153
155
## Examples
154
156
@@ -159,7 +161,10 @@ defmodule Kaffy.ResourceAdmin do
159
161
```
160
162
"""
161
163
def ordering ( resource ) do
162
- Utils . get_assigned_value_or_default ( resource , :ordering , desc: :id )
164
+ schema = resource [ :schema ]
165
+ [ order_key | _ ] = ResourceSchema . primary_keys ( schema )
166
+
167
+ Utils . get_assigned_value_or_default ( resource , :ordering , desc: order_key )
163
168
end
164
169
165
170
@ doc """
@@ -331,6 +336,70 @@ defmodule Kaffy.ResourceAdmin do
331
336
Utils . get_assigned_value_or_default ( resource , :plural_name , default )
332
337
end
333
338
339
+ @ doc """
340
+ `serialize_id/2` takes a schema and record and must return a string to be used in the URL and form values.
341
+
342
+ If `serialize_id/2` is not defined, Kaffy will concatenate multiple primary keys with `":"` as a separator.
343
+
344
+ Examples:
345
+
346
+ ```elixir
347
+ # Default method with fixed keys
348
+ def serialize_id(_schema, record) do
349
+ Enum.join([record.post_id, record.tag_id], ":")
350
+ end
351
+
352
+ # ETF
353
+ def serialize_id(_schema, record) do
354
+ {record.post_id, record.tag_id}
355
+ |> :erlang.term_to_binary()
356
+ |> Base.url_encode64()
357
+ end
358
+ ```
359
+ """
360
+ def serialize_id ( resource , entry ) do
361
+ schema = resource [ :schema ]
362
+ default = schema
363
+ |> ResourceSchema . primary_keys ( )
364
+ |> Enum . map_join ( @ default_id_separator , & Map . get ( entry , & 1 ) )
365
+
366
+ Utils . get_assigned_value_or_default ( resource , :serialize_id , default , [ entry ] )
367
+ end
368
+
369
+ @ doc """
370
+ `deserialize_id/2` takes a schema and serialized id and must return a complete
371
+ keyword list in the form of [{:primary_key, value}, ...].
372
+
373
+ If `deserialize_id/2` is not defined, Kaffy will split multiple primary keys with `":"` as a separator.
374
+
375
+ Examples:
376
+
377
+ ```elixir
378
+ # Default method with fixed keys
379
+ def deserialize_id(_schema, serialized_id) do
380
+ Enum.zip([:post_id, :tag_id], String.split(serialized_id, ":"))
381
+ end
382
+
383
+ # Deserialize from ETF
384
+ def deserialize_id(_schema, serialized_id) do
385
+ {product_id, tag_id} = serialized_id
386
+ |> Base.url_decode64!()
387
+ |> :erlang.binary_to_term()
388
+
389
+ [product_id: product_id, tag_id: tag_id]
390
+ end
391
+ ```
392
+ """
393
+ def deserialize_id ( resource , id ) do
394
+ schema = resource [ :schema ]
395
+ id_list = String . split ( id , @ default_id_separator )
396
+ default = schema
397
+ |> ResourceSchema . primary_keys ( )
398
+ |> Enum . zip ( id_list )
399
+
400
+ Utils . get_assigned_value_or_default ( resource , :deserialize_id , default , [ id ] )
401
+ end
402
+
334
403
def resource_actions ( resource , conn ) do
335
404
Utils . get_assigned_value_or_default ( resource , :resource_actions , nil , [ conn ] , false )
336
405
end
0 commit comments