diff --git a/lib/jsonapi/serializer.ex b/lib/jsonapi/serializer.ex index 0dfeb72d..7523afa5 100644 --- a/lib/jsonapi/serializer.ex +++ b/lib/jsonapi/serializer.ex @@ -112,13 +112,14 @@ defmodule JSONAPI.Serializer do # Build the relationship url rel_key = transform_fields(relationship_name) rel_url = parent_view.url_for_rel(parent_data, rel_key, conn) + rr_url = parent_view.url_for_rr(parent_data, rel_key, conn) # Build the relationship acc = put_in( acc, [:relationships, rel_key], - encode_relation({rel_view, rel_data, rel_url, conn}) + encode_relation({rel_view, rel_data, rel_url, rr_url}) ) valid_include_view = include_view(valid_includes, relationship_name) @@ -215,7 +216,7 @@ defmodule JSONAPI.Serializer do end @spec encode_relation(tuple()) :: map() - def encode_relation({rel_view, rel_data, _rel_url, _conn} = info) do + def encode_relation({rel_view, rel_data, _rel_url, _rr_url} = info) do data = %{ data: encode_rel_data(rel_view, rel_data) } @@ -283,10 +284,10 @@ defmodule JSONAPI.Serializer do defp merge_related_links( encoded_data, - {rel_view, rel_data, rel_url, conn}, + {_rel_view, _rel_data, rel_url, rr_url}, true = _add_auto_links ) do - Map.merge(encoded_data, %{links: %{self: rel_url, related: rel_view.url_for(rel_data, conn)}}) + Map.merge(encoded_data, %{links: %{self: rel_url, related: rr_url}}) end defp merge_related_links(encoded_rel_data, _info, _add_auto_links), do: encoded_rel_data diff --git a/lib/jsonapi/view.ex b/lib/jsonapi/view.ex index 7406e545..8eb73f91 100644 --- a/lib/jsonapi/view.ex +++ b/lib/jsonapi/view.ex @@ -244,6 +244,7 @@ defmodule JSONAPI.View do @callback url_for(data(), Conn.t() | nil) :: String.t() @callback url_for_pagination(data(), Conn.t(), Paginator.params()) :: String.t() @callback url_for_rel(term(), String.t(), Conn.t() | nil) :: String.t() + @callback url_for_rr(term(), String.t(), Conn.t() | nil) :: String.t() @callback visible_fields(data(), Conn.t() | nil) :: list(atom) @optional_callbacks [get_field: 3] @@ -379,6 +380,10 @@ defmodule JSONAPI.View do def url_for_rel(data, rel_type, conn), do: View.url_for_rel(__MODULE__, data, rel_type, conn) + @impl View + def url_for_rr(data, rel_type, conn), + do: View.url_for_rr(__MODULE__, data, rel_type, conn) + @impl View def visible_fields(data, conn), do: View.visible_fields(__MODULE__, data, conn) @@ -524,6 +529,11 @@ defmodule JSONAPI.View do "#{url_for(view, data, conn)}/relationships/#{rel_type}" end + @spec url_for_rr(t(), data(), String.t(), Conn.t() | nil) :: String.t() + def url_for_rr(view, data, relationship_key, conn) do + "#{url_for(view, data, conn)}/#{relationship_key}" + end + @spec url_for_rel(t(), data(), Conn.query_params(), Paginator.params()) :: String.t() def url_for_pagination( view, diff --git a/test/jsonapi/serializer_test.exs b/test/jsonapi/serializer_test.exs index 38579a92..ff7f2189 100644 --- a/test/jsonapi/serializer_test.exs +++ b/test/jsonapi/serializer_test.exs @@ -530,12 +530,13 @@ defmodule JSONAPI.SerializerTest do best_comments: [] } - encoded = Serializer.serialize(PostView, data, nil) - - encoded_data = encoded[:data] - - assert encoded_data[:relationships][:author][:links][:self] == - "/mytype/1/relationships/author" + assert %{ + data: %{ + relationships: %{ + author: %{links: %{self: "/mytype/1/relationships/author", related: "/mytype/1/author"}} + } + } + } = Serializer.serialize(PostView, data, nil) end test "serialize handles a relationship self link on an index request" do diff --git a/test/jsonapi/view_test.exs b/test/jsonapi/view_test.exs index 2aa2758a..4356eb3d 100644 --- a/test/jsonapi/view_test.exs +++ b/test/jsonapi/view_test.exs @@ -155,13 +155,20 @@ defmodule JSONAPI.ViewTest do assert PostView.url_for([], %Plug.Conn{}) == "http://www.example.com/api/posts" assert PostView.url_for([], %Plug.Conn{port: 123}) == "http://www.example.com:123/api/posts" assert PostView.url_for(%{id: 1}, %Plug.Conn{}) == "http://www.example.com/api/posts/1" + end + test "url_for_rel/2" do assert PostView.url_for_rel([], "comments", %Plug.Conn{}) == "http://www.example.com/api/posts/relationships/comments" assert PostView.url_for_rel(%{id: 1}, "comments", %Plug.Conn{}) == "http://www.example.com/api/posts/1/relationships/comments" end + + test "url_for_rr/2" do + assert PostView.url_for_rr(%{id: 1}, "comments", %Plug.Conn{}) == + "http://www.example.com/api/posts/1/comments" + end end describe "url_for/2 when host configured" do