Hi all,
Finally think I have enough of a grasp on Elixir and Ecto to formulate this question.
Basically, I’m looking to implement the same functionality that the Public Activity gem brings to a Rails app, tracking user activity.
Using an example of comments, let’s say users can comment on other users and on some other models, say cars and boats.
In Rails you’d have:
* commentable_type
* commentable_id
the Ecto docs point out:
The problem with this approach is that it breaks references in the database. You can’t use foreign keys and it is very inefficient, both in terms of query time and storage.
From what I can tell based on comments on some of the original ecto issues and various SO questions, Ecto would encourage two options which Bill Karwin terms:
- Exclusive Arcs: Create multiple foreign key columns, each referencing one parent. Enforce that exactly one of these foreign keys can be non-NULL.
- Concrete Supertable: Instead of the implicit “commentable” superclass, create a real table that each of your parent tables references. Then link your Comments to that supertable.
This makes sense for the comments example above, and I can happily have user_comments
, boat_comments
, and car_comments
In contrast, the case of tracking activity seems much more unwieldy, as can be seen by the model used by Public Activity (code paraphrased)
# Define resource being tracked
belongs_to :trackable, :polymorphic => true
...
# Define ownership to a resource responsible for this activity
belongs_to :owner, :polymorphic => true
# Define ownership to a resource targeted by this activity
belongs_to :recipient, :polymorphic => true
I couldn’t think through a way to transfer that sort of polymorphism to the patterns in the Ecto docs:
Another aspect was trying to think through the end goal. Ultimately, it seems like the what I’m trying to accomplish is “log” the changes made to the database by users. In a sense storing store metadata about the database itself (or past states) in the database.
Any suggestions on how to accomplish this? Or alternatives methods of tracking how the database has changed?
Thanks!
Sources:
Ecto - Support polymorphic belongs to #389
SO - Why can you not have a foreign key in a polymorphic association?
Ecto - Ecto.Schema Docs