Reputation: 27114
This is rife with problems and unlike anything I've witnessed with SQL. I'm simply trying to create an HABTM relationship and make the objects match each other.
My Two Models
class Word
include MongoMapper::Document
many :topics
key :word, String
end
class Topic
include MongoMapper::Document
many :words
key :name, String
end
That model work alone allows me to create objects and associate them. Part of why I love Mongo.
Then I try to take some sample yaml like so :
Music I Dig:
reggae:
bob marley
isaac hayes
groundation
classical:
philip glass
bach
And trying to parse it with this 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
I kid you not, this is the most random, jangled output I've ever seen. 2 the amount of actual topics are created that are empty and have no data. Some topics have associations, some done. Same with words. Some words will randomly have associations, and other won't. I can't find any connection at all as to how its deriving this outcome.
I believe the problem comes with how I'm setting up my models ( maybe? ). If not, I'm throwing mongo_mapper and trying Mongoid.
Upvotes: 3
Views: 437
Reputation: 369
Firstly, you'll need to specify that word_ids and topic_ids are array attributes in your models:
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
You'll also have to make sure that you are saving your topic and word in your rake task:
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
That gives me the following output:
{
"_id" : ObjectId("502bc54a3005c83a3a000006"),
"topic_ids" : [
ObjectId("502bc54a3005c83a3a000001")
],
"word" : "groundation",
"type" : "reggae"
}
{
"_id" : ObjectId("502bc54a3005c83a3a000007"),
"topic_ids" : [
ObjectId("502bc54a3005c83a3a000001")
],
"word" : "philip",
"type" : "classical"
} ....etc
and
{
"_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"
}
Upvotes: 4