2009-11-29 11 views
3

J'ai ces deux cours,DataMapper a n par des ressources SUPPRIMER (Retirer de l'association) ne fonctionne pas

class User 
    include DataMapper::Resource 
    property :id, Serial 
    property :name, String 

    has n :posts, :through => Resource 

end 

class Post 
    include DataMapper::Resource 
    property :id, Serial 
    property :title, String 
    property :body, Text 

    has n :users, :through => Resource 
end 

Donc une fois que j'ai un nouveau poste comme:

Post.new(:title => "Hello World", :body = "Hi there").save 

Je suis ayant de sérieux problèmes à ajouter et à retirer de l'association, comme:

User.first.posts << Post.first #why do I have to save this as oppose from AR? 
(User.first.posts << Post.first).save #this just works if saving the insertion later 

Et comment dois-je supprimer un message de cette association? J'utilise les éléments suivants, mais sans aucun doute sa ne fonctionne pas:

User.first.posts.delete(Post.first) #returns the Post.first, but nothing happens 
User.first.posts.delete(Post.first).save #returns true, but nothing happens 
User.first.posts.delete(Post.first).destroy #destroy the Post.first, not the association 

Je ne sais vraiment pas comment supprimer du tableau du BoltUser.

Répondre

4

La méthode delete() et d'autres méthodes de Array ne fonctionnent que sur la copie en mémoire des collections. Ils ne modifient réellement rien jusqu'à ce que vous persister les objets.

De plus, toutes les actions CRUD exécutées sur une collection affectent principalement la cible. Quelques-uns, comme create() ou destroy(), ajouteront/supprimeront les ressources intermédiaires dans de nombreuses collections, mais ce n'est qu'un effet secondaire de la création ou de la suppression de la cible.

Dans votre cas, si vous voulez simplement supprimer le premier message, vous pouvez le faire:

User.first.posts.first(1).destroy 

La partie User.first.posts.first(1) retourne une collection scope seulement le premier poste. Appeler détruire sur la collection supprime tout dans la collection (qui n'est que le premier enregistrement) et inclut les intermédiaires.

+0

Merci pour l'explication Dan, cette méthode que vous avez mentionnée a également fonctionné! Salutations – zanona

+0

Est-ce que create() n'est pas déprécié? Mais je comprends que new() fonctionne maintenant de la même manière pour une collection, de sorte que User.first.posts.new() créera et conservera un enregistrement? – arbales

+0

Non, create() n'est pas obsolète. new() initialise juste la ressource en mémoire. Cependant, il le lie à l'objet parent, ainsi l'enregistrement du parent entraînera la sauvegarde de l'enfant. – dkubb

0

j'ai réussi à le faire en faisant:

#to add 
user_posts = User.first.posts 
user_posts << Bolt.first 
user_posts.save 

#to remove 
user_posts.delete(Bolt.first) 
user_posts.save 

Je pense que la seule façon de le faire est de travailler avec les actions d'exemple, faites vos changements sur cette instance et après avoir terminé, juste enregistrer.

C'est un peu différent de l'AR, mais ça devrait aller.