У DataMapper через Resource DELETE (Удалить из ассоциации) не работает

У меня есть два класса,

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.


person zanona    schedule 29.11.2009    source источник


Ответы (2)


Метод delete() и другие методы из Array работают только с копиями коллекций в памяти. На самом деле они ничего не изменяют, пока вы не сохраните объекты.

Кроме того, все действия CRUD, выполняемые над коллекцией, в первую очередь влияют на цель. Некоторые из них, такие как create() или destroy(), будут добавлять/удалять промежуточные ресурсы во многих-многих коллекциях, но это лишь побочный эффект создания или удаления цели.

В вашем случае, если вы хотите удалить только первое сообщение, вы можете сделать это:

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

Часть User.first.posts.first(1) возвращает коллекцию только для первого сообщения. Вызов уничтожения коллекции удаляет все в коллекции (это только первая запись) и включает посредников.

person dkubb    schedule 30.11.2009
comment
Спасибо за объяснение, Дэн, этот метод, который вы упомянули, тоже сработал! Ваше здоровье - person zanona; 30.11.2009
comment
Разве create() не устарела? Но я понимаю, что new() теперь работает одинаково для коллекции, так что User.first.posts.new() создаст и сохранит запись? - person arbales; 19.12.2009
comment
Нет, create() не устарел. new() просто инициализирует ресурс в памяти. Однако он связывает его с родительским объектом, поэтому сохранение родителя приведет к сохранению и дочернего объекта. - person dkubb; 04.01.2010

Мне удалось сделать это, выполнив:

#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, но должно быть хорошо.

person Community    schedule 11.08.2014