MongoDB creates parent objects when I try to creat

2019-09-17 13:24发布

This model:

class SimCustomer < Customer
  index({ user_id: 1 },       { background: true })
  belongs_to :user,           :inverse_of => :sim_customers
end

inherits from this model:

class Customer
  include Mongoid::Document
  include Mongoid::Timestamps
  field :mail_address,        type: String
end

I create the indexes from my terminal:

bundle exec rake db:mongoid:create_indexes

But this creates indexes on the Customer instead of the SimCustomer:

I, [2014-11-13T16:21:17.210343 #11407]  INFO -- : MONGOID: Created indexes on Customer:
I, [2014-11-13T16:21:17.210381 #11407]  INFO -- : MONGOID: Index: {:user_id=>1}, Options: {:background=>true}

And when I try to batch insert SimCustomer objects it creates Customer objects instead:

SimCustomer.collection.insert(Array.new << {mail_address: "hello@hello.com", user_id: "54652f5b43687229b4060000"})
# => #<Customer _id: 54654b7b6220ff4f28364ee9, created_at: nil, updated_at: nil, mail_address: "hello@hello.com", _type: "Customer">

How can I fix this?

1条回答
戒情不戒烟
2楼-- · 2019-09-17 13:46

This sets up Single Collection Inheritance:

class SimCustomer < Customer

That means that both Customer and SimCustomer will be stored in the customers collection inside MongoDB and they'll be differentiated using the _type field.

Specifying an index in SimCustomer:

class SimCustomer < Customer
  index({ user_id: 1 },       { background: true })

will create the index on the customers collection because that's where SimCustomers are stored.

The same collection chicanery is causing your problem with your bulk insert. If you look at SimCustomer.collection.name you'll find that it says 'customers' so of course SimCustomer.collection.insert will create new Customers. If you want to create SimCustomers by hand then specify the _type:

SimCustomer.collection.insert(
  _type: 'SimCustomer',
  mail_address: "hello@hello.com",
  user_id: "54652f5b43687229b4060000"
)

Note that I dropped that strange looking Array.new << stuff, I don't know where you learned that from but it is unnecessary when inserting on object and odd looking if you were inserting several, if you want to insert several then just use an array literal:

SimCustomer.collection.insert([
  { ... },
  { ... },
  ...
])

Your next problem is going to be that string in user_id. That really should be a Moped::BSON::ObjectId or you'll end up with a string inside the database and that will make a mess of your queries. Mongoid may know what type a property should be but neither Moped nor MongoDB will. You'll want to use Moped::BSON::ObjectId('54652f5b43687229b4060000') instead.

查看更多
登录 后发表回答