2014-12-22 4 views
0

У меня есть три модели: колоды, слоты и карты. Я собрал их так ... Палубы сделаны из множества слотов, каждый слот содержит одну карту, и любая карта может отображаться в нескольких разных слотах. Я смоделировал его после структуры «Order - Order Line Item - Product», надеюсь, что это имеет смысл.Ассоциация активных записей после запроса «.where»

В любом случае, колоды имеют целое поле, называемое: deck_type, и предположим, что я хочу получить все колоды определенного типа, а затем увидеть все их карты. Я ожидаю, чтобы быть в состоянии выполнить этот запрос, но я получаю ошибку неопределенного метода «карты»:

Deck.where(:deck_type => 1).cards 

Чтобы получить все палубы 1-го типа, а затем выплюнуть свои карты. У меня установлена ​​ассоциация «колода имеет много карт через слоты», и когда я называю «карты» на одной колоде, она отлично работает, чтобы вернуть карты.

Я чувствую, что это должен быть довольно простой запрос - чего мне не хватает?

Заранее благодарим за понимание.

ответ

3

Метод cards предназначен для одной колоды. Таким образом, следующие должны работать:

Deck.where(deck_type: 1).first.cards 

first будет получать 1 колоду.

Если вы хотите карты, принадлежащие палуб с deck_type 1, то у вас есть несколько вариантов:

Deck.where(deck_type: 1).map(&:cards).flatten.uniq 

Это будет применяться метод cards на каждой найденной палубе, а затем получить все карты. Сглаживание сделает результаты в 1D-массив, а затем uniq обеспечит отсутствие дубликатов, если таковые имеются.

Но следующее может быть быстрее:

deck_ids = Deck.where(deck_type: 1).pluck(:id) 
Card.where(deck_id: deck_ids) 

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

Еще лучше, однако, было бы следующим, поскольку это будет один запрос базы данных. Если предположить, что у вас есть настройки правильные ассоциации, вы можете сделать:

# replace 'decks' with Deck.table_name if necessary 
Card.joins(:deck).where(decks: {deck_type: 1}) 

Я надеюсь, что в прошлом один говорит само за себя.

+0

Благодарим вас за скорый ответ и прекрасную информацию - представленный вами вариант карты и сглаживания возвращает карты, которые я ищу совершенно! У меня нет поля: deck_id в таблице карт, так как они связаны с колодами через таблицу слотов - это имеет смысл или моя модель не собирается работать? На палубах много карточек и карточек могут быть на многих колодах, поэтому я хотел избегать отношений «многие ко многим», если это возможно, помещая таблицу слотов между ними. –

+1

считают, что у вас есть связь между колодами и картами, так что последняя команда, которую я написал, может работать. Это быстрее, чем карта (&: cards) .flatten.uniq – Humza

+0

Палубная модель - «has_many: cards,: through =>: slots» ... это позволяет мне получать карты через колоды, но это скорее вызов вернуться палубы через карты, так как я не могу поместить на карту карт «own_to: decks,: through =>: slots» (по крайней мере, не то, что я знаю). Тем не менее, я все еще довольно новичок в этом, так что изучение того, как работает .map, является фантастическим и позволяет мне использовать одну линию для выполнения действий, которые обычно занимают несколько! –

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