@@ -440,6 +440,28 @@ defmodule Mongo.Collection do
440
440
"modified" : ISODate("2020-05-19T15:15:14.374Z"),
441
441
"title" : "Vega"
442
442
}
443
+
444
+ ## Example `Inlined Collections`
445
+
446
+ You can define an embedded collection inline. In the following example, the `Person.Friend`
447
+ and `Person.Pet` modules are automatically defined for you.
448
+
449
+ defmodule Person do
450
+ use Mongo.Collection
451
+
452
+ collection "persons" do
453
+ attribute :name, String.t()
454
+
455
+ embeds_one :friend, Friend do
456
+ attribute :name, String.t()
457
+ end
458
+
459
+ embeds_many :pets, Pet, default: [] do
460
+ attribute :name, String.t()
461
+ end
462
+ end
463
+ end
464
+
443
465
## Example `timestamps`
444
466
445
467
defmodule Post do
@@ -879,8 +901,25 @@ defmodule Mongo.Collection do
879
901
@ doc """
880
902
Adds the struct to the `embeds_one` list. Calls `__embeds_one__`
881
903
"""
882
- defmacro embeds_one ( name , mod , opts \\ [ ] ) do
904
+ defmacro embeds_one ( name , mod , opts \\ [ ] )
905
+
906
+ defmacro embeds_one ( name , mod , do: block ) do
907
+ quote do
908
+ embeds_one ( unquote ( name ) , unquote ( mod ) , [ ] , do: unquote ( block ) )
909
+ end
910
+ end
911
+
912
+ defmacro embeds_one ( name , mod , opts ) do
913
+ quote do
914
+ Collection . __embeds_one__ ( __MODULE__ , unquote ( name ) , unquote ( mod ) , unquote ( opts ) )
915
+ end
916
+ end
917
+
918
+ defmacro embeds_one ( name , mod , opts , do: block ) do
919
+ mod = expand_nested_module_alias ( mod , __CALLER__ )
920
+
883
921
quote do
922
+ Collection . __embeds_module__ ( __ENV__ , unquote ( mod ) , unquote ( Macro . escape ( block ) ) )
884
923
Collection . __embeds_one__ ( __MODULE__ , unquote ( name ) , unquote ( mod ) , unquote ( opts ) )
885
924
end
886
925
end
@@ -895,8 +934,26 @@ defmodule Mongo.Collection do
895
934
@ doc """
896
935
Adds the struct to the `embeds_many` list. Calls `__embeds_many__`
897
936
"""
898
- defmacro embeds_many ( name , mod , opts \\ [ ] ) do
937
+ defmacro embeds_many ( name , mod , opts \\ [ ] )
938
+
939
+ defmacro embeds_many ( name , mod , do: block ) do
899
940
quote do
941
+ embeds_many ( unquote ( name ) , unquote ( mod ) , [ ] , do: unquote ( block ) )
942
+ end
943
+ end
944
+
945
+ defmacro embeds_many ( name , mod , opts ) do
946
+ quote do
947
+ type = unquote ( Macro . escape ( { { :. , [ ] , [ mod , :t ] } , [ ] , [ ] } ) )
948
+ Collection . __embeds_many__ ( __MODULE__ , unquote ( name ) , unquote ( mod ) , type , unquote ( opts ) )
949
+ end
950
+ end
951
+
952
+ defmacro embeds_many ( name , mod , opts , do: block ) do
953
+ mod = expand_nested_module_alias ( mod , __CALLER__ )
954
+
955
+ quote do
956
+ Collection . __embeds_module__ ( __ENV__ , unquote ( mod ) , unquote ( Macro . escape ( block ) ) )
900
957
type = unquote ( Macro . escape ( { { :. , [ ] , [ mod , :t ] } , [ ] , [ ] } ) )
901
958
Collection . __embeds_many__ ( __MODULE__ , unquote ( name ) , unquote ( mod ) , type , unquote ( opts ) )
902
959
end
@@ -910,6 +967,19 @@ defmodule Mongo.Collection do
910
967
Module . put_attribute ( mod , :embed_manys , { name , target , add_name ( mod , opts , name ) } )
911
968
end
912
969
970
+ def __embeds_module__ ( env , mod , block ) do
971
+ block =
972
+ quote do
973
+ use Collection
974
+
975
+ document do
976
+ unquote ( block )
977
+ end
978
+ end
979
+
980
+ Module . create ( mod , block , env )
981
+ end
982
+
913
983
@ doc """
914
984
Adds the attribute to the attributes list. It call `__attribute__/4` function.
915
985
"""
@@ -1080,4 +1150,12 @@ defmodule Mongo.Collection do
1080
1150
|> Map . new ( )
1081
1151
end
1082
1152
end
1153
+
1154
+ defp expand_nested_module_alias ( { :__aliases__ , _ , [ Elixir , _ | _ ] = alias } , _env ) ,
1155
+ do: Module . concat ( alias )
1156
+
1157
+ defp expand_nested_module_alias ( { :__aliases__ , _ , [ h | t ] } , env ) when is_atom ( h ) ,
1158
+ do: Module . concat ( [ env . module , h | t ] )
1159
+
1160
+ defp expand_nested_module_alias ( other , _env ) , do: other
1083
1161
end
0 commit comments