Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Mongoid's "Custom Primary & Foreign Keys" behavior. #3097

Conversation

dongsheng2014
Copy link

In the latest (7.0.2) mongoid document Mongoid|Associations, primary and foreign keys
can be customized for an association. As a result, we can't assume an association's foreign key is "_id(s)" and primary key is "_id".

With primary & foreign keys customization, below modes:

  class Company
    include Mongoid::Document
    # This definition of e_refs is automatically generated by Mongoid:
    # But the type can also be specified:
    field :e_refs, type: Array
    has_and_belongs_to_many :emails, foreign_key: 'e_refs', primary_key: 'e'
  end

  class Email
    include Mongoid::Document
    field :e, type: Object

	rails_admin do
	  object_label_method do
	    :e
	  end
	end
  end

will have the documents stored as follows:

  # The company document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "e_refs": ["a@example.com", "b@example.com"]
  }

  # The email document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f1"),
    "e" : "a@example.com"
  },
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f2"),
    "e" : "b@example.com"
  }

In the latest (7.0.2) mongoid document (https://docs.mongodb.com/mongoid/master/tutorials/mongoid-relations/), primary and foreign keys
can be customized for an association. As a result, we can't assume that the foreign key is "<name>_id(s)" and primary key is
"_id".

With primary & foreign keys customization, below modes:

  class Company
    include Mongoid::Document
    # This definition of e_refs is automatically generated by Mongoid:
    # But the type can also be specified:
    field :e_refs, type: Array
    has_and_belongs_to_many :emails, foreign_key: 'e_refs', primary_key: 'e'
  end

  class Email
    include Mongoid::Document
    field :e, type: Object

	rails_admin do
	  object_label_method do
	    :e
	  end
	end
  end

will have the documents stored as follows:

  \# The company document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "e_refs": ["a@example.com", "b@example.com"]
  }

  \# The email document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f1"),
    "e" : "a@example.com"
  },
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f2"),
    "e" : "b@example.com"
  }
This method is used by fields with has_and_belongs_to_many association to retrieve the name of the <ref>_ids setter.
ActiveRecord always uses <ref>_ids, whereas Mongoid may have different setter name if foreign_key option is present.
@mshibuya
Copy link
Member

Test needed!

@dongsheng2014
Copy link
Author

Test needed!

As this commit is version dependent (mongoid >= 7.0.2), I can write some test specs for this version, i.e., to have some associations (e.g., has_and_belongs_to_many) with primary_key and foreign_key options, but they will fail on all lower versions. Could you give me some advice?

@mshibuya mshibuya added this to the 3.0.0 milestone Oct 8, 2021
@mshibuya mshibuya closed this in 3f67637 Oct 23, 2021
@mshibuya
Copy link
Member

Fixed by 3f67637 in a slightly different way. Thanks for the PR anyway!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants