0
votes

So I am trying to make a content system in phoenix, where there are courses, folders, and lessons, and object is the backbone of everything, so:

Object:

has_many :children, Content.Object
belongs_to :parent, Content.Object

Course

belongs_to :object, Content.Object

Folder

belongs_to :object, Content.Object

This method has a problem, though. I can't seem to find a way to get the folder from a course. I want to be able to do something like this:

iex(1)> course = Content.get_course!(1)
iex(2)> [folderObj | _] = course.object.children
iex(3)> folder = folderObj.item

But obviously the item field doesn't exist on object. How would I add this? (Also I can add more code if it isn't clear, just comment)

1

1 Answers

2
votes

The rule of thumb is: If you find yourself naming something “Object” you are doing it wrong.

Even if the code you provided was building what you expect, course.object.children would have returned a collection of both courses and folders, and there was no way to grab the head of this list and expect it’d be a folder (as you do in the line 2.) Also, we do not have a polymorphism in OOP meaning in . Course is a Course, it cannot be also “somewhat Object.”

So you should separately build a tree of the objects. For that, your object schema looks fine, and the internets are full of examples of how to build a tree.

Besides children, the object should have many courses, many folders and many lessons. Then the call to course.object.folders (assuming everything is preloaded properly) would result in the collection of folders as you wanted.

To get to all the folders, including those belonging to children, you would need to implement the recursive walk through the tree children, the applicable algorithms are beyond the subject here.

Of course, there could be many other ways to impolement the similar functionality, but for what you shared that one seems to be the most robust.