DataMapper tiene n a través del recurso DELETE (Eliminar de la asociación) no funciona
-
07-07-2019 - |
Pregunta
Tengo estas dos clases,
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
Entonces, una vez que tengo una nueva publicación como:
Post.new(:title => "Hello World", :body = "Hi there").save
Tengo problemas serios para agregar y eliminar de la asociación, como:
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
¿Y cómo debo eliminar una publicación de esa asociación? Estoy usando lo siguiente pero definitivamente no funciona:
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
Así que realmente no sé cómo eliminar esto del BoltUser Array.
Solución
El método delete () y otros métodos de Array solo funcionan en la copia en memoria de las Colecciones. En realidad, no modifican nada hasta que persiste los objetos.
Además, todas las acciones CRUD realizadas en una colección afectan principalmente al objetivo. Algunos, como create () o destroy (), agregarán / eliminarán los recursos intermedios en muchas colecciones, pero es solo un efecto secundario de crear o eliminar el objetivo.
En su caso, si desea eliminar solo la primera publicación, puede hacer esto:
User.first.posts.first(1).destroy
La parte User.first.posts.first (1)
devuelve una colección con alcance solo en la primera publicación. Llamar a destruir en la colección elimina todo en la colección (que es solo el primer registro) e incluye a los intermediarios.
Otros consejos
Logré hacerlo haciendo:
#to add
user_posts = User.first.posts
user_posts << Bolt.first
user_posts.save
#to remove
user_posts.delete(Bolt.first)
user_posts.save
Creo que la única forma de hacerlo es trabajar con las acciones de la instancia, hacer los cambios en esa instancia y, una vez que haya terminado, simplemente guárdela.
Es un poco diferente de AR, pero debería estar bien.