当我尝试创建子对象时,MongoDB创建父对象

时间:2014-11-14 00:39:57

标签: ruby-on-rails mongodb mongoid

此型号:

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

继承自此模型:

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

我从终端创建索引:

bundle exec rake db:mongoid:create_indexes

但这会在Customer上创建索引,而不是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}

当我尝试批量插入SimCustomer个对象时,它会创建Customer个对象:

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">

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

这将设置单一集合继承:

class SimCustomer < Customer

这意味着CustomerSimCustomer都会存储在MongoDB中的customers集合中,并且会使用_type字段进行区分。

SimCustomer中指定索引:

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

将在customers集合上创建索引,因为这是存储SimCustomer的位置。

同样的集合诡计导致您的批量插入问题。如果您查看SimCustomer.collection.name,您会发现它显示为'customers',因此当然SimCustomer.collection.insert会创建新的Customer。如果您想手动创建SimCustomer,请指定_type

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

请注意,我删除了那些看起来很奇怪的Array.new <<内容,我不知道你从哪里学到了这些内容但是在插入对象时是不必要的,如果要插入几个,则奇怪的看,如果你想插入几个然后只使用数组文字:

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

您的下一个问题将是user_id中的字符串。那真的应该是Moped::BSON::ObjectId,否则你最终会在数据库中找到一个字符串,这将使你的查询变得混乱。 Mongoid可能知道属性应该是什么类型,但是Moped和MongoDB都不会。您需要使用Moped::BSON::ObjectId('54652f5b43687229b4060000')代替。