mongify icon indicating copy to clipboard operation
mongify copied to clipboard

Embed by Reference Support

Open paul-uulabs opened this issue 4 years ago • 4 comments

The current table-level embed_in implementation requires the child to reference the parent by id... but there seems to be no way to embed if the parent references the child...

For example, the following will create a reference to an address (child) within "companies" (parent):

table "addresses" do
	column "address1", :string
	column "address2", :string
	column "suite", :string
	column "city", :string
	column "province", :string
	column "country", :string
	column "phone", :string
	column "zip", :string
	column "created", :datetime
	column "modified", :datetime
	column "id", :key, :as => :integer
end

table "companies" do
	column "title", :string
	column "description", :string
	column "email", :string
	column "website", :string
	column "organizationType", :integer
	column "addressId", :integer, :references => :addresses 
	column "created", :datetime
	column "modified", :datetime
	column "id", :key, :as => :integer
end

... BUT I want to embed the address record in companies... companies has a reference to address only.

Is it possible for Mongify to embed by reference... ?

For example, it would be great if I could do this on the column level:

column "addressId", :integer, :references => :addresses, embed_in=>true

... or maybe there is a way of doing this that I don't understand?

paul-uulabs avatar Nov 24 '20 23:11 paul-uulabs

Unfortunately, this is not doable without a bunch of custom code.

You should be able to pull it off, if you use before_save on company, and use the addressId and look up the address manually. To do so, you'd have to read the source code to understand the internals.

anlek avatar Nov 25 '20 22:11 anlek

Thank you and that's good to hear. I've looked at the code, but would it be possible to point me in the right direction? I am not sure how to insert a query in a before_save. I'm surprised no one has asked about this.

paul-uulabs avatar Nov 26 '20 12:11 paul-uulabs

@paul-uulabs looks like you might be able to use before_save and flip the association. Checkout: https://github.com/anlek/mongify/blob/master/lib/mongify/database/table.rb#L52

anlek avatar Nov 26 '20 17:11 anlek

Thanks @anlek,

I managed to use before_save to embed address references in companies, like I want... BUT the company record is still embedded into addresses in the end... so I end up with address>company>address ... if I could update the company table and stop the embed, I'd have what I want (company>address)... I am not sure if that is what you meant by "flip the association" ..? I cannot flip the tables completely (i.e.: rename "address" tables as "company", embed, and finally move the fields around) because addresses are referenced by several tables, not just companies... I don't know if it is possible to access the table object in before_save to embed the address record into the company collection, etc..?

This is what I have...?

table "addresses" do
	column "title", :string
	column "address1", :string, :rename_to => 'addressStreet' 
	column "address2", :string, :rename_to => 'addressSecondary'
	column "suite", :string
	column "city", :string
	column "province", :string
	column "country", :string
	column "phone", :string
	column "zip", :string
	column "addressType", :integer
	column "description", :string
	column "email", :string
	column "created", :datetime
	column "modified", :datetime
	column "id", :key, :as => :integer
end

table "companies", :embed_in => :addresses, :on => :addressId do
	column "title", :string
	column "description", :string
	column "email", :string
	column "website", :string
	column "organizationType", :integer
	column "addressId", :integer, :references => :addresses 
	column "created", :datetime
	column "modified", :datetime
	column "id", :key, :as => :integer
	before_save do |row, parent_row|
		row.address = {}
		if parent_row.title
			row.address["title"] = parent_row.title
			row.address["address1"] = parent_row.addressStreet
			row.address["address2"] = parent_row.addressSecondary
			row.address["suite"] = parent_row.suite
			row.address["city"] = parent_row.city
			row.address["province"] = parent_row.province
			row.address["country"] = parent_row.country
			row.address["phone"] = parent_row.phone
			row.address["zip"] = parent_row.zip
			row.address["addressType"] = parent_row.addressType
			row.address["description"] = parent_row.description
			row.address["email"] = parent_row.email
			row.address["created"] = parent_row.created
			row.address["modified"] = parent_row.modified
		end
	end
end

Also, I found a limitation in before_save... notice that my properties in addresses include "address1" and "address2"... Mongify strips out numeric characters in fields in data_row.rb so I could not access them in before_save unless I renamed them.

paul-uulabs avatar Nov 27 '20 13:11 paul-uulabs