Skip to content

Commit 4f2df85

Browse files
committed
load association for activities
drop transaction activities and 'second' level activities associated with a user
1 parent b15808b commit 4f2df85

File tree

4 files changed

+108
-58
lines changed

4 files changed

+108
-58
lines changed

lib/algora/activities/activities.ex

Lines changed: 100 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ defmodule Algora.Activities do
55
alias Algora.Accounts.User
66
alias Algora.Activities.Activity
77
alias Algora.Repo
8+
alias Ecto.Multi
89

910
@tables [
1011
:identity_activities,
@@ -43,9 +44,7 @@ defmodule Algora.Activities do
4344
:owned_installations,
4445
:connected_installations,
4546
:client_contracts,
46-
{:client_contracts, :transactions},
4747
:client_contracts,
48-
{:contractor_contracts, :transactions},
4948
:contractor_contracts
5049
]
5150

@@ -67,20 +66,19 @@ defmodule Algora.Activities do
6766
end
6867

6968
def base_query(table_name) when is_binary(table_name) do
70-
from(_e in {table_name, Activity})
69+
assoc_name = schema_from_table(table_name)
70+
base = from(e in {table_name, Activity})
71+
72+
from(u in subquery(base),
73+
select_merge: %{
74+
id: u.id,
75+
type: u.type,
76+
assoc_id: u.assoc_id,
77+
assoc_name: ^table_name
78+
}
79+
)
7180
end
7281

73-
# def base_query({parent_table_name, table_name}) do
74-
# parent = to_string(parent_table_name)
75-
# child = to_string(table_name)
76-
77-
# parent_table_name
78-
# |> base_query()
79-
# |> join(:inner, [p], assoc(p, ^parent), as: :parent)
80-
# |> join(:inner, [c], assoc(c, ^child), as: :child)
81-
# |> join(:inner, [a], assoc(a, :activities), as: :activities)
82-
# end
83-
8482
def base_query_for_user(user_id) do
8583
[head | tail] = @user_attributes
8684
first_query = base_query_for_user(user_id, head)
@@ -91,21 +89,22 @@ defmodule Algora.Activities do
9189
end)
9290
end
9391

94-
def base_query_for_user(user_id, {parent_table_name, table_name}) do
95-
from u in User,
96-
where: u.id == ^user_id,
97-
join: p in assoc(u, ^parent_table_name),
98-
join: c in assoc(p, ^table_name),
99-
join: a in assoc(c, :activities),
100-
select: a
101-
end
102-
103-
def base_query_for_user(user_id, name) do
104-
from u in User,
105-
where: u.id == ^user_id,
106-
join: c in assoc(u, ^name),
107-
join: a in assoc(c, :activities),
108-
select: a
92+
def base_query_for_user(user_id, relation_name) do
93+
table_name = table_from_user_relation(relation_name)
94+
assoc_name = schema_from_table(table_name)
95+
96+
base =
97+
from u in User,
98+
where: u.id == ^user_id,
99+
join: c in assoc(u, ^relation_name),
100+
join: a in assoc(c, :activities),
101+
select: %{
102+
id: a.id,
103+
type: a.type,
104+
assoc_id: a.assoc_id,
105+
assoc_name: ^table_name,
106+
inserted_at: a.inserted_at
107+
}
109108
end
110109

111110
def all(table_name) when is_binary(table_name) do
@@ -126,20 +125,90 @@ defmodule Algora.Activities do
126125
base_query()
127126
|> order_by(fragment("inserted_at DESC"))
128127
|> limit(40)
129-
|> Repo.all()
128+
|> all_with_assoc()
130129
end
131130

132131
def all_for_user(user_id) do
133132
user_id
134133
|> base_query_for_user()
135134
|> order_by(fragment("inserted_at DESC"))
136135
|> limit(40)
137-
|> Repo.all()
136+
|> all_with_assoc()
138137
end
139138

140139
def insert(target, activity) do
141140
target
142141
|> Activity.build_activity(activity)
143142
|> Algora.Repo.insert()
144143
end
144+
145+
def all_with_assoc(query) do
146+
multi =
147+
Multi.new()
148+
|> Multi.run(:activities, fn repo, _changes ->
149+
{:ok, repo.all(query)}
150+
end)
151+
|> Multi.run(:associations, fn repo, %{activities: activities} ->
152+
associations =
153+
Enum.map(activities, fn activity ->
154+
repo.one(from b in schema_from_table(activity.assoc_name), where: b.id == ^activity.assoc_id)
155+
end)
156+
157+
{:ok, associations}
158+
end)
159+
|> Multi.run(:preloaded, fn _repo, %{activities: activities, associations: assocs} ->
160+
preloaded =
161+
Enum.zip_with(activities, assocs, fn act, assoc ->
162+
Map.put(act, :assoc, assoc)
163+
end)
164+
165+
{:ok, preloaded}
166+
end)
167+
168+
case Repo.transaction(multi) do
169+
{:ok, %{preloaded: preloaded} = a} ->
170+
preloaded
171+
172+
{:error, _step, reason, _changes} ->
173+
reason
174+
# Handle error
175+
end
176+
end
177+
178+
def schema_from_table("identity_activities"), do: Algora.Accounts.Identity
179+
def schema_from_table("user_activities"), do: Algora.Accounts.User
180+
def schema_from_table("attempt_activities"), do: Algora.Bounties.Attempt
181+
def schema_from_table("bonus_activities"), do: Algora.Bounties.Bonus
182+
def schema_from_table("bounty_activities"), do: Algora.Bounties.Bounty
183+
def schema_from_table("claim_activities"), do: Algora.Bounties.Claim
184+
def schema_from_table("tip_activities"), do: Algora.Bounties.Tip
185+
def schema_from_table("message_activities"), do: Algora.Chat.Message
186+
def schema_from_table("thread_activities"), do: Algora.Chat.Thread
187+
def schema_from_table("contract_activities"), do: Algora.Contracts.Contract
188+
def schema_from_table("timesheet_activities"), do: Algora.Contracts.Timesheet
189+
def schema_from_table("application_activities"), do: Algora.Jobs.Application
190+
def schema_from_table("job_activities"), do: Algora.Jobs.Job
191+
def schema_from_table("account_activities"), do: Algora.Payments.Account
192+
def schema_from_table("customer_activities"), do: Algora.Payments.Customer
193+
def schema_from_table("payment_method_activities"), do: Algora.Payments.PaymentMethod
194+
def schema_from_table("platform_transaction_activities"), do: Algora.Payments.PlatformTransaction
195+
def schema_from_table("transaction_activities"), do: Algora.Payments.Transaction
196+
def schema_from_table("project_activities"), do: Algora.Projects.Project
197+
def schema_from_table("review_activities"), do: Algora.Reviews.Project
198+
def schema_from_table("installation_activities"), do: Algora.Workplace.Installation
199+
def schema_from_table("ticket_activities"), do: Algora.Workspace.Ticket
200+
def schema_from_table("repository_activities"), do: Algora.Workspace.Repository
201+
202+
def table_from_user_relation(:attempts), do: "attempt_activities"
203+
def table_from_user_relation(:claims), do: "claim_activities"
204+
def table_from_user_relation(:client_contracts), do: "contract_activities"
205+
def table_from_user_relation(:connected_installations), do: "installation_activities"
206+
def table_from_user_relation(:contractor_contracts), do: "contract_activities"
207+
def table_from_user_relation(:created_bounties), do: "bounty_activities"
208+
def table_from_user_relation(:owned_bounties), do: "bounty_activities"
209+
def table_from_user_relation(:identities), do: "identity_activities"
210+
def table_from_user_relation(:owned_installations), do: "installation_activities"
211+
def table_from_user_relation(:projects), do: "project_activities"
212+
def table_from_user_relation(:repositories), do: "repository_activities"
213+
def table_from_user_relation(:transactions), do: "transaction_activities"
145214
end

lib/algora/activities/schemas/activity.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ defmodule Algora.Activities.Activity do
2525
field :changes, :map, default: %{}
2626
field :trace_id, :string
2727
field :notify_users, {:array, :string}, default: []
28+
field :assoc_name, :string, virtual: true
2829

2930
belongs_to :user, Algora.Accounts.User
3031
belongs_to :previous_event, __MODULE__

lib/algora/contracts/contracts.ex

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,7 @@ defmodule Algora.Contracts do
178178
|> foreign_key_constraint(:contract_id)
179179
|> foreign_key_constraint(:timesheet_id)
180180
|> foreign_key_constraint(:user_id)
181-
|> Repo.insert_with_activity(%{
182-
type: :transaction_created
183-
})
181+
|> Repo.insert()
184182
end
185183

186184
defp initialize_debit(%{id: id, contract: contract, amount: amount, linked_transaction_id: linked_transaction_id}) do
@@ -205,9 +203,7 @@ defmodule Algora.Contracts do
205203
|> foreign_key_constraint(:contract_id)
206204
|> foreign_key_constraint(:timesheet_id)
207205
|> foreign_key_constraint(:user_id)
208-
|> Repo.insert_with_activity(%{
209-
type: :transaction_created
210-
})
206+
|> Repo.insert()
211207
end
212208

213209
defp initialize_credit(%{id: id, contract: contract, amount: amount, linked_transaction_id: linked_transaction_id}) do
@@ -232,9 +228,7 @@ defmodule Algora.Contracts do
232228
|> foreign_key_constraint(:contract_id)
233229
|> foreign_key_constraint(:timesheet_id)
234230
|> foreign_key_constraint(:user_id)
235-
|> Repo.insert_with_activity(%{
236-
type: :transaction_created
237-
})
231+
|> Repo.insert()
238232
end
239233

240234
defp initialize_transfer(%{contract: contract, amount: amount}) do
@@ -258,9 +252,7 @@ defmodule Algora.Contracts do
258252
|> foreign_key_constraint(:contract_id)
259253
|> foreign_key_constraint(:timesheet_id)
260254
|> foreign_key_constraint(:user_id)
261-
|> Repo.insert_with_activity(%{
262-
type: :transaction_created
263-
})
255+
|> Repo.insert()
264256
end
265257

266258
defp initialize_prepayment_transaction(contract) do

test/algora/contracts_test.exs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,24 +235,9 @@ defmodule Algora.ContractsTest do
235235
assert_activity_names_for_user(
236236
contract_a_0.contractor_id,
237237
[
238-
:transaction_created,
239238
:contract_prepaid,
240-
:transaction_created,
241-
:transaction_created,
242-
:transaction_created,
243-
:transaction_created,
244-
:transaction_status_change,
245-
:transaction_status_change,
246-
:transaction_status_change,
247239
:contract_paid,
248240
:contract_renewed,
249-
:transaction_created,
250-
:transaction_created,
251-
:transaction_created,
252-
:transaction_created,
253-
:transaction_status_change,
254-
:transaction_status_change,
255-
:transaction_status_change,
256241
:contract_paid,
257242
:contract_renewed
258243
]
@@ -265,6 +250,9 @@ defmodule Algora.ContractsTest do
265250
Activities.all_for_user(contract_b_0.contractor_id)
266251

267252
assert_enqueued(worker: Activities.Notifier, worker: "Algora.Activities.Notifier")
253+
254+
assert [contract_activity | _rest] = Enum.reverse(Activities.all())
255+
assert contract_activity.assoc.id == contract_a_0.id
268256
end
269257

270258
test "prepayment fails when payment method is invalid" do

0 commit comments

Comments
 (0)