I'm trying to create a Mongoid N-N reference association between two embedded documents in Rails 4 however I'm finding it difficult to get my head round how this is done.
I started by adding the HABTM association to the relevant models below (Track
and Option
) but of course I'm getting the error saying this isn't allowed because they're both embedded.
class Brief
embeds_many :tracks
end
class Track
embedded_in :brief
has_and_belongs_to_many :options
end
and
class Category
embeds_many :options
end
class Option
field :name, type: String
field :track_ids, type: Array
embedded_in :category
has_and_belongs_to_many :tracks
def parent
self.category
end
def tracks
self.parent.tracks.where(:option_id => self.id)
end
end
I completely understand why this is and know I need to reference the parent documents but here is where I run into trouble.
Ive been trying to add track ids to the track_ids
via the console array but I end up getting the same error as before:
"Problem: Referencing a(n) Track document from the Option document via a relational association is not allowed since the Track is embedded. Summary: In order to properly access a(n) Track from Option the reference would need to go through the root document of Track. In a simple case this would require Mongoid to store an extra foreign key for the root, in more complex cases where Track is multiple levels deep a key would need to be stored for each parent up the hierarchy."
I would be happy to store the extra foreign key but I have no idea how and in what format. If anybody can point me in the right direction I would appreciate it.
The reason you are getting the error is because of the logic below. If you are going to need to represent many-to-many relations, do not use a document model to store your state. Use a relational one
===
You can't represent a many to many relation without an association/reference table/object. If you don't have a reference table, then your update to either end could cause an infinite update as all your relations (and then their relations) will be touched (and possibly re-saved)
For example,
Track 1, => Option 1, 2, 3
Option 1, => Track 1, 2, 3
Track 2, => Option 1, 2
Option 2, => Track 1, 2
Track 3, => Option 1, 3, 4
Option 3, => Track 1, 3, 4
Now let's go ahead and edit Track 1,
1) update Track 1
2) Causes update in options 1, 2, 3
3) option 1 caused re=update of track 1, (infinite repeat of 1,2,3)
4) option 2 causes update of Tracks 1, 2 (infinite repeat again)
5) etc...