2011-05-02 4 views
1

J'ai un document MongoId qui intègre d'autres documents avec une relation comme ceci:MongoId: Changer l'ordre des documents dans une relation embeds_many

embeds_many: blocs

La création de nouveaux blocs fonctionne très bien, mais je ne peux pas parvient à modifier l'ordre des documents incorporés existants. Par exemple, j'ai trois blocs intégrés et je veux déplacer le dernier à la première position .Quelle est la bonne façon de faire cela?

Répondre

2

je devais traiter cela avec la fonction de recursively_embeds_many de MongoId, mais il est essentiellement le même. Pour autant que je sache, il n'y a rien de mal à réécrire littéralement le document. Ecrivez une méthode de modèle pour faire quelque chose comme:

def reverse_blocks 
    reversed_blocks = blocks.to_a.reverse 
    blocks.clear 
    reversed_blocks.each do |b| 
    blocks.create b.attributes 
    end 
    save 
end 

C'est le code pas grand-dessus, mais il vous donne une idée de la façon de faire ce que vous voulez faire. Je ne suis pas ravi d'avoir à passer par là pour réorganiser des choses dans un tableau, mais il est là.

+0

Cela ne semble pas fonctionner (plus? - J'utilise mongoid 3.0.9). Sans duper b.attributes je reçois une erreur à cause d'un hachage gelé. Et puis je rencontre des problèmes avec _id/_type non accessible (attr_accessible). Donc, je devais désactiver la protection d'assignation de masse (que je ne veux pas de toute façon) –

+0

Vous pourriez avoir raison. Cela a été définitivement découvert sur Mongoid 2. Vous allez vouloir conditionner les b.attributs pour ne plus être que les champs que vous voulez copier, en omettant le _id, _type, etc. La méthode des attributs doit fonctionner différemment en 3, je peux seulement supposer. – jeremy6d

+0

Si vous souhaitez conserver les attributs protégés (_id, _type, etc ...), vous devrez les définir explicitement. par exemple: 'new_block = blocks.build (b.attributes)' 'new_block._id = b._id' ' new_block.save' – Matt

1

Je pense que cette façon vraiment correcte est de faire dans le champ "poids" de vos docs et de les interroger avec asc (: weight) ou desc (: weight). Vous ne comptez pas sur l'ordre des documents persistants non incorporés, vous ne devriez donc pas l'incorporer.

Mais si vous avez besoin de toute urgence pour faire cela, vos documents intégrés dans MongoId sont ensemble juste, afin que vous puissiez le faire de telle manière:

doc.embedded_docs = [doc.embedded_docs.last] + doc.embedded_docs[0..-2] 
+0

J'ai essayé, mais le tableau est vide après!? Je vois ce comportement aussi si j'essaye "reverse" ou quelque chose comme ça. Utilisation: le poids n'est pas une option. J'utilise MongoDB parce que je ne veux pas le faire de la "manière SQL". ;-) – Achim

+0

J'ai reçu des commentaires de la liste mongodb. Le déplacement d'éléments à un seul tableau n'est pas possible. Il faut réécrire le document, mais cela ne semble pas possible avec Mongoid et les documents incorporés. Donc, votre solution en utilisant un poids/commande semble être la meilleure - même si je ne l'aime pas. : -/ – Achim

+0

réellement MongoDB n'est pas une pure solution NoSQL, mais une sorte d'hybride d'approche relationnelle et NoSQL. Je pense donc qu'une telle méthode est plutôt efficace. – sandrew

Questions connexes