add polymorphic association loader

This commit is contained in:
byte[] 2019-11-15 22:06:37 -05:00
parent ca15e74c4a
commit ec26c0e4d4
4 changed files with 58 additions and 0 deletions

View file

@ -11,6 +11,9 @@ defmodule Philomena.Notifications.Notification do
field :actor_child_id, :integer
field :actor_child_type, :string
field :actor, :any, virtual: true
field :actor_child, :any, virtual: true
timestamps(inserted_at: :created_at)
end

View file

@ -0,0 +1,53 @@
defmodule Philomena.Polymorphic do
alias Philomena.Repo
import Ecto.Query
@classes %{
"Channel" => Philomena.Channels.Channel,
"Comment" => Philomena.Comments.Comment,
"Commission" => Philomena.Commissions.Commission,
"Conversation" => Philomena.Conversations.Conversation,
"Filter" => Philomena.Filters.Filter,
"Forum" => Philomena.Forums.Forum,
"Gallery" => Philomena.Galleries.Gallery,
"Image" => Philomena.Images.Image,
"LivestreamChannel" => Philomena.Channels.Channel,
"Post" => Philomena.Posts.Post,
"Topic" => Philomena.Topics.Topic,
"User" => Philomena.Users.User
}
# Deal with Rails polymorphism BS
def load_polymorphic(structs, associations) when is_list(associations) do
Enum.reduce(associations, structs, fn asc, acc -> load_polymorphic(acc, asc) end)
end
def load_polymorphic(structs, {name, {id, type}}) do
modules_and_ids =
structs
|> Enum.group_by(& &1[type], & &1[id])
loaded_rows =
modules_and_ids
|> Map.new(fn
{nil, _ids} ->
{nil, []}
{type, ids} ->
rows =
@classes[type]
|> where([m], m.id in ^ids)
|> Repo.all()
|> Map.new(fn r -> {r.id, r} end)
{type, rows}
end)
structs
|> Enum.map(fn struct ->
row = loaded_rows[struct[type]][struct[id]]
%{struct | name => row}
end)
end
end

View file

@ -18,6 +18,8 @@ defmodule Philomena.Reports.Report do
field :reportable_id, :integer
field :reportable_type, :string
field :reportable, :any, virtual: true
timestamps(inserted_at: :created_at)
end