0

У меня есть три модели:Mongoid, как сохранить отношения в синхронизации для общей родительской модели?

Agency 
has_many :owners 
has_many :properties 

Owner 
belongs_to :agency 
has_many :properties 

Property 
belongs_to :owner 
belongs_to :agency 

agency.properties соотношение должно относиться ко всем свойствам, что все владельцы имеют, но когда я создаю свойство внутри владельца, agency.properties отношения не создаются. Я хочу, чтобы это отношение было автоматически выполнено, а также удалено, когда владелец или свойство удалено.

Как я могу достичь такого поведения с мангоидом?

ответ

0

Поскольку это довольно конкретный прецедент, невозможно «автоматически» сделать это, используя мангоид «из коробки». То, что я хотел бы предложить вам, - это иметь некоторые before_save крючки, которые гарантировали бы состояние ваших отношений. Вы также, в зависимости от вашего варианта использования, Имущество может быть денормализованным (встроенным) объектом внутри Владельца и Агентства.

+0

Хорошо. Как вы думаете, будет ли соответствующая проблема с производительностью, как я это делаю? – jturolla

+0

Да, если у вас есть большие коллекции, синхронизировать те, что has_many будет влиять на записи. Также помните, что Mongodb не имеет атомных транзакций для нескольких коллекций, поэтому у вас могут быть непоследовательные данные. –

1

Вы также могли бы написать что-то вроде:

Agency 
has_many :owners 

Owner 
belongs_to :agency 
has_many :properties 

Property 
belongs_to :owner 

А затем добавить метод экземпляра в модели агентства:

def properties 
owners.map(&:properties).flatten.uniq 
end 

Однако этот подход будет опрашивать базу данных для извлечения владельцев, а затем будет запрашивать вашу БД снова один раз для каждого владельца, чтобы получить свойства каждого владельца.

Надеюсь, это поможет.

EDIT

Существует еще одно решение, которое подразумевает только 2 запросов:

def properties 
Property.where({:owner_id.in => owner_ids}) 
end 

ПРОФИ:

Он использует только два запроса.

Он возвращает критерии Mongoid (предыдущее решение вернуло массив). Таким образом, вы можете цепи прицелы и так далее (т.е. my_agency.properties.sold #if вы определили продаваемый объем)

CONS:

Этот код кажется менее читаемым.

Кроме того, он менее ремонтопригодным. Если вы измените внешний ключ в отношении Owner-Property, вы должны обновить этот метод (Property.where ({: foreign_key ...}) или изменить способ, которым владелец имеет много свойств. Первый вариант все еще действует до тех пор, пока все свойства владельца можно найти с помощью метода экземпляра some_owner.properties.

+0

это великолепно, но представляет проблему n + 1. – jturolla

+0

@ JúlioTurollaRibeiro. спросите: «Сколько владельцев может иметь агентство? десять или т тысячи? И насколько быстро этот запрос будет?" Тогда:" Есть ли истинная связь между агентствами и свойствами? или агентства имеют свойства только потому, что у них есть владельцы, которые, в свою очередь, обладают свойствами? »По мере того как ваше приложение растет, насколько легко/сложно будет поддерживать синхронизацию всех отношений? –

+0

@ JúlioTurollaRibeiro. Я отредактировал ответ с помощью just-2 -queries, но он вводит некоторые другие вопросы, касающиеся обслуживания кода. С уважением –

Смежные вопросы