Однажды при использовании Datamapper столкнулся с задачей обновления коллекции отношений many_to_many, перерыл множество источников, но толкового объяснение так и не нашел. Хочу представить мое решение.
Итак, у нас есть 2 объекта — Статья (Article) и Категория (Category). Одна Статья может принадлежать разным Категориям и одна Категория может содержать несколько Статей. Сразу создадим несколько Категорий.
Мы решили создать Статью «Жерар Депардье» и решили что она может лежать в нескольких Категориях — «Действующие актеры», «Французы»
Спустя некоторое время мы решили внести изменения — удалить Статью из Категории «Действующие актеры», добавить в Категорию «Виноделы», и добавить в Категорию «Россияне».
И вот тут происходит самое интересное потому, что можно сделать как описано в документации — вручную удалять связи ненужные и добавлять новые, а можно сделать гораздо проще — просто присвоить массив необходимых связей.
Надеюсь что мое объяснение будет полезным, а если кто знает вариант проще — прошу рассказать в комментариях.
Итак, у нас есть 2 объекта — Статья (Article) и Категория (Category). Одна Статья может принадлежать разным Категориям и одна Категория может содержать несколько Статей. Сразу создадим несколько Категорий.
class Article
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :categories, :through => Resource
end
class Category
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :articles, :through => Resource
end
category_d = Category.new
category_d.name = "Действующие актеры"
category_d.save
category_f = Category.new
category_f.name = "Французы"
category_f.save
category_v = Category.new
category_v.name = "Виноделы"
category_v.save
category_r = Category.new
category_r.name = "Россияне"
category_r.save
Мы решили создать Статью «Жерар Депардье» и решили что она может лежать в нескольких Категориях — «Действующие актеры», «Французы»
article = Article.new
article.name = "Жерар Депардье"
article.save
category_d = Category.first(:name => "Действующие актеры")
category_f = Category.first(:name => "Французы")
article.categories << category_d
article.categories << category_f
article.save
Спустя некоторое время мы решили внести изменения — удалить Статью из Категории «Действующие актеры», добавить в Категорию «Виноделы», и добавить в Категорию «Россияне».
И вот тут происходит самое интересное потому, что можно сделать как описано в документации — вручную удалять связи ненужные и добавлять новые, а можно сделать гораздо проще — просто присвоить массив необходимых связей.
article = Article.first(:name => "Жерар Депардье")
category_v = Category.first(:name => "Виноделы")
category_r = Category.first(:name => "Россияне")
category_f = Category.first(:name => "Французы")
article.categories = [category_v, category_r, category_f]
article.save
Надеюсь что мое объяснение будет полезным, а если кто знает вариант проще — прошу рассказать в комментариях.