@@ -42,7 +42,7 @@ defmodule JSONAPI.Serializer do
4242 encoded_data
4343 end
4444
45- merge_links ( encoded_data , data , view , conn , query_page , remove_links ?( ) , options )
45+ merge_links ( encoded_data , data , view , conn , query_page , add_auto_links ?( ) , options , true )
4646 end
4747
4848 def encode_data ( _view , nil , _conn , _query_includes , _options ) , do: { [ ] , nil }
@@ -67,7 +67,7 @@ defmodule JSONAPI.Serializer do
6767 relationships: % { }
6868 }
6969
70- doc = merge_links ( encoded_data , data , view , conn , nil , remove_links ?( ) , options )
70+ doc = merge_links ( encoded_data , data , view , conn , nil , add_auto_links ?( ) , options , false )
7171
7272 doc =
7373 case view . meta ( data , conn ) do
@@ -210,42 +210,76 @@ defmodule JSONAPI.Serializer do
210210 data: encode_rel_data ( rel_view , rel_data )
211211 }
212212
213- merge_related_links ( data , info , remove_links ?( ) )
213+ merge_related_links ( data , info , add_auto_links ?( ) )
214214 end
215215
216- defp merge_base_links ( % { links: links } = doc , data , view , conn ) do
217- view_links = data |> view . links ( conn ) |> Map . merge ( links )
218- Map . merge ( doc , % { links: view_links } )
216+ defp merge_links ( doc , data , view , conn , _page , false , _options , is_root_of_doc ) do
217+ merge_view_links ( doc , data , view , conn , is_root_of_doc )
219218 end
220219
221- defp merge_links ( doc , data , view , conn , page , false , options ) when is_list ( data ) do
222- links =
220+ defp merge_links ( doc , data , view , conn , page , true , options , is_root_of_doc ) do
221+ doc
222+ |> merge_auto_links ( data , view , conn , page , options )
223+ |> merge_view_links ( data , view , conn , is_root_of_doc )
224+ end
225+
226+ defp merge_view_links ( doc , data , view , conn , is_root_of_doc )
227+
228+ defp merge_view_links ( % { links: links } = doc , data , view , conn , false ) do
229+ # intentionally take the view.links and merge them into the existing links,
230+ # allowing the custom defined links for the view to override any auto-links
231+ # generated by this library UNLESS configured to remove links (backwards
232+ # compatibility):
233+ view_links =
234+ if remove_links? ( ) do
235+ % { }
236+ else
237+ Map . merge ( links , view . links ( data , conn ) )
238+ end
239+
240+ new_doc = Map . merge ( doc , % { links: view_links } )
241+
242+ case new_doc do
243+ % { links: links } when links == % { } ->
244+ Map . delete ( doc , :links )
245+
246+ doc ->
247+ doc
248+ end
249+ end
250+
251+ defp merge_view_links ( doc , data , view , conn , false ) ,
252+ do: merge_view_links ( Map . merge ( doc , % { links: % { } } ) , data , view , conn , false )
253+
254+ defp merge_view_links ( doc , _data , _view , _conn , true ) , do: doc
255+
256+ defp merge_auto_links ( doc , data , view , conn , page , options )
257+ when is_list ( data ) do
258+ auto_links =
223259 data
224260 |> view . pagination_links ( conn , page , options )
225- |> Map . merge ( % { self: view . url_for_pagination ( data , conn , page ) } )
261+ |> Map . merge ( % {
262+ self: view . url_for_pagination ( data , conn , page )
263+ } )
226264
227- doc
228- |> Map . merge ( % { links: links } )
229- |> merge_base_links ( data , view , conn )
265+ Map . merge ( doc , % { links: auto_links } )
230266 end
231267
232- defp merge_links ( doc , data , view , conn , _page , false , _options ) do
233- doc
234- |> Map . merge ( % { links: % { self: view . url_for ( data , conn ) } } )
235- |> merge_base_links ( data , view , conn )
236- end
268+ defp merge_auto_links ( doc , data , view , conn , _page , _options ) do
269+ auto_links = % { self: view . url_for ( data , conn ) }
237270
238- defp merge_links ( doc , _data , _view , _conn , _page , _remove_links , _options ) , do: doc
271+ Map . merge ( doc , % { links: auto_links } )
272+ end
239273
240274 defp merge_related_links (
241275 encoded_data ,
242276 { rel_view , rel_data , rel_url , conn } ,
243- false = _remove_links
277+ true = _add_auto_links
244278 ) do
245279 Map . merge ( encoded_data , % { links: % { self: rel_url , related: rel_view . url_for ( rel_data , conn ) } } )
246280 end
247281
248- defp merge_related_links ( encoded_rel_data , _info , _remove_links ) , do: encoded_rel_data
282+ defp merge_related_links ( encoded_rel_data , _info , _add_auto_links ) , do: encoded_rel_data
249283
250284 @ spec encode_rel_data ( module ( ) , map ( ) | list ( ) ) :: map ( ) | nil
251285 def encode_rel_data ( _view , nil ) , do: nil
@@ -302,7 +336,13 @@ defmodule JSONAPI.Serializer do
302336 |> List . flatten ( )
303337 end
304338
305- defp remove_links? , do: Application . get_env ( :jsonapi , :remove_links , false )
339+ defp remove_links? do
340+ Application . get_env ( :jsonapi , :remove_links , false )
341+ end
342+
343+ defp add_auto_links? do
344+ Application . get_env ( :jsonapi , :add_auto_links , ! remove_links? ( ) )
345+ end
306346
307347 @ spec serialize_nil_relationships? :: boolean ( )
308348 defp serialize_nil_relationships? , do: Application . get_env ( :jsonapi , :serialize_nil_relationships , false )
0 commit comments