3

这充满了问题,与我所见过的 SQL 不同。我只是想创建一个 HABTM 关系并使对象相互匹配。

我的两个模型

class Word
  include MongoMapper::Document         

  many :topics

  key :word, String

end

class Topic
  include MongoMapper::Document         

  many :words

  key :name, String

end

该模型单独工作允许我创建对象并将它们关联。我喜欢 Mongo 的部分原因。

然后我尝试像这样获取一些示例 yaml:

Music I Dig:
  reggae:
    bob marley
    isaac hayes
    groundation
  classical:
    philip glass
    bach

并尝试用这个 Rakefile 解析它:

File.open(Rails.root + 'lib/words/disgusting_glass_full_of.yml', 'r') do |file|
  YAML::load(file).each do |topic, word_types|
    puts "Adding #{topic}.."
    @temp_topic = Topic.create name: topic

    @temp_words = word_types.map { |type, words|
      words.split(' ').map{ |word| 
        @word = Word.create type: type, word: word
        @word.topics << @temp_topic
      }
    }
    @temp_topic.words << @temp_words.flatten
  end
end

我不骗你,这是我见过的最随机、最混乱的输出。2 创建的实际主题数量为空且没有数据。有些主题有关联,有些已经完成。词也一样。有些单词会随机产生关联,而有些则不会。关于它是如何得出这个结果的,我根本找不到任何联系。

我相信问题在于我如何设置模型(也许?)。如果没有,我将抛出 mongo_mapper 并尝试 Mongoid。

4

1 回答 1

4

首先,您需要指定 word_ids 和 topic_ids 是模型中的数组属性:

  class Topic
    include MongoMapper::Document         

    many :words, :in => :word_ids
    key :word_ids, Array
    key :name, String
  end

class Word
  include MongoMapper::Document         

  many :topics, :in => :topic_ids
  key :topic_ids, Array
  key :word, String

end

您还必须确保在您的 rake 任务中保存您的主题和单词:

task :import => :environment do
  File.open(Rails.root + 'lib/test.yml', 'r') do |file|
    YAML::load(file).each do |topic, word_types|
      puts "Adding #{topic}.."
      temp_topic = Topic.create name: topic
      temp_words = []
      word_types.map do |type, words|
        words.split(' ').map do |word|
          word = Word.create type: type, word: word
          word.topics << temp_topic
          word.save
          temp_words << word
        end
      end
      temp_topic.words << temp_words.flatten
      temp_topic.save
    end
  end  
end

这给了我以下输出:

{
    "_id" : ObjectId("502bc54a3005c83a3a000006"),
    "topic_ids" : [
        ObjectId("502bc54a3005c83a3a000001")
    ],
    "word" : "groundation",
    "type" : "reggae"
}
{
    "_id" : ObjectId("502bc54a3005c83a3a000007"),
    "topic_ids" : [
        ObjectId("502bc54a3005c83a3a000001")
    ],
    "word" : "philip",
    "type" : "classical"
}  ....etc

{
    "_id" : ObjectId("502bc54a3005c83a3a000001"),
    "word_ids" : [
        ObjectId("502bc54a3005c83a3a000002"),
        ObjectId("502bc54a3005c83a3a000003"),
        ObjectId("502bc54a3005c83a3a000004"),
        ObjectId("502bc54a3005c83a3a000005"),
        ObjectId("502bc54a3005c83a3a000006"),
        ObjectId("502bc54a3005c83a3a000007"),
        ObjectId("502bc54a3005c83a3a000008"),
        ObjectId("502bc54a3005c83a3a000009")
    ],
    "name" : "Music I Dig"
}
于 2012-08-15T15:57:23.220 回答