У DataMapper через Resource DELETE (Удалить из ассоциации) не работает
-
07-07-2019 - |
Вопрос
У меня есть эти два класса,
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
Итак, когда у меня появилось новое сообщение вроде:
Post.new(:title => "Hello World", :body = "Hi there").save
У меня серьезные проблемы с добавлением и удалением из ассоциации, например:
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
И как мне удалить сообщение из этой ассоциации? Я использую следующее, но оно определенно не работает:
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
Так что я действительно не знаю, как удалить это из массива BoltUser.
Решение
Метод delete () и другие методы из массива работают только с копией коллекций в памяти. Они ничего не изменяют, пока вы не сохраните объекты.
Кроме того, все действия CRUD, выполняемые над коллекцией, в первую очередь влияют на цель. Некоторые из них, такие как create () или destroy (), будут добавлять / удалять промежуточные ресурсы во многих коллекциях, но это лишь побочный эффект создания или удаления цели.
В вашем случае, если вы хотите удалить только первое сообщение, вы можете сделать это:
User.first.posts.first(1).destroy
Часть User.first.posts.first (1)
возвращает коллекцию, ограниченную только первым сообщением. Вызов уничтожения для коллекции удаляет все в коллекции (которая является только первой записью) и включает посредников.
Другие советы
Мне удалось сделать это, выполнив:
#to add
user_posts = User.first.posts
user_posts << Bolt.first
user_posts.save
#to remove
user_posts.delete(Bolt.first)
user_posts.save
Я думаю, что единственный способ сделать это - работать с действиями экземпляра, вносить изменения в этом экземпляре, а после завершения просто сохранить его.
Это немного отличается от AR, но все должно быть хорошо.