2016-07-26 3 views
0

Я пишу программу, где элементы имеют несколько характеристик и несколько значений, а значения относятся к элементам и характеристикам. Мне нужно иметь возможность добавлять значения и характеристики в таблицу элементов несколько раз каждый (неограниченное количество раз).Rails Unlimited Self Joins As Alias ​​

Есть ли способ получить таблицы соединений, которые выглядят так, с синтаксисом ruby?

SELECT items.* 
FROM items 
INNER JOIN characteristics ON characteristics.item_id = items.id AS characteristics1 
INNER JOIN values ON value_items.item_id = item.id AS value1 
INNER JOIN characteristics ON characteristics.item_id = items.id AS characteristics2 
INNER JOIN values ON value_items.item_id = item.id AS value2 
WHERE characteristics1.id = 1 AND 
WHERE values1.value = "foo" AND 
WHERE characteristics2.id = 2 AND 
WHERE values2.value = "bar" 

Это, как минимум, на самом деле, я должен иметь возможность связывать неограниченное количество самостоятельных соединений.

EDIT: работа с решением - еще нет.

Item.joins(:values).where("values.value=?", "foo").where("values.characteristic_id = 2") 

Это работает, чтобы найти предметы, основанные на одной из характеристик. Однако, когда я пытаюсь найти элементы, которые удовлетворяют критерии по нескольким характеристикам, которые я получаю ActiveRecord::StatementInvalid: PG::DatatypeMismatch: ERROR: argument of WHERE must be type boolean, not type record

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

Item.joins(:values).where("values.value=?", ["foo", "bar"]).where("values.characteristic_id=?", [1, 2]) 

Item.includes(:values).where("values.value=?", ["foo", "bar"]).where("values.characteristic_id=?", [1, 2]).references(:values) 
+0

Было бы здорово, если бы вы делились отношениями между моделями и тем, что вы пытаетесь достичь. –

+0

В основном то, что я делаю, позволяет пользователям создавать свои собственные таблицы.Пользователи решают, какие характеристики они хотят, присваивают значения этим характеристикам, а затем могут сортировать и фильтровать собственные таблицы, созданные пользователем. Таким образом, пользователи могут назначить неограниченное количество характеристик для своей таблицы. –

+0

Не позволю мне по каким-либо причинам редактировать или просто поставить отношения на ОП. Элемент has_many: значения. Значение принадлежит_to: item. Значение принадлежит_от: характеристика. Характеристика has_many: значения. Характеристика принадлежит_to: collection. Коллекция has_many: items. Коллекция has_many: характеристики. –

ответ

0

хорошее решение

я в основном просто разучились работать псевдонимами. Это то, что я хочу:

Item.joins("INNER JOIN values v1 on v1.item_id = items.id") 
.joins("INNER JOIN values v2 on v2.item_id = items.id") 
.where(v1: {characteristic_id: 1, value: "foo"}) 
.where(v2: {characteristic_id: 2, value: "bar}) 

Грозного Решение

Я нашел временное решение, используя рубин вне ActiveRecord.

search1 = Item.joins(:values).where(values: {characteristic_id: 1, value: "foo"}) 

search2 = Item.joins(:values).where(values: {characteristic_id: 2, value: "bar"}) 

Item.find(search1.map(&:id) & search2.map(&:id)) 

Я мог бы на самом деле нужно сделать это рекурсивно, так как я не могу определить search1 и Search2 переменные, так как мне нужно неограниченное количество поисков. Или, может быть, метапрограммирование.

Конечно, было бы лучше сделать это в одном запросе. Возможно, мне просто нужно написать метод, который генерирует необработанный SQL. Тем не менее, вы ищете способ получить псевдонимы на соединениях через рельсы.

+0

Хорошее решение, используя скручивание, будет быстрее, чем карта. Вы могли бы создать область для этого в своей модели, и вы могли бы использовать ту же область, где бы вы ни понадобились. –

+0

Я думаю, что решение карты - это плохое решение. То, что мне было нужно, это то, что «values ​​v1» является частью верхнего решения. –

0

При создании модели Active Record имеет способность использовать ассоциации. Это позволит вам добавить файлы has_many и/или принадлежит вашим файлам моделей. См. Пример ниже.

класс Автор < ApplicationRecord has_many: книги, зависимый:: разрушающие конец

класс Книга < ApplicationRecord belongs_to: автор конец

Rails поддерживает шесть типов ассоциаций:

belongs_to 
has_one 
has_many 
has_many :through 
has_one :through 
has_and_belongs_to_many 
+0

Мои ассоциации уже настроены. –

+0

Выполняет присоединение к args. Данный символ (символы) должен совпадать с именем ассоциации (ассоциаций). User.joins (: сообщения,: счета) # производят следующий запрос # SELECT "пользователи" * # FROM "пользователей" # INNER Join "сообщения" ON "сообщений" "user_id" = «пользователи.. "." id " # INNER JOIN" accounts "ON" accounts "." id "=" users "." account_id " –

+0

Я знаю, как получить внутреннее соединение. Я несколько раз присоединяюсь к себе, я хочу знать, как это сделать в рельсах (я знаю, как это сделать в SQL). Попытайтесь попробовать решение Вайбхава завтра утром и убедитесь, что оно работает. –

1

Если у вас есть отношения в моделях, Items.includes(:characteristics,:value_items).where('characteristics.id=?',[1,2]).references(:characteristics).where('values_items.value=?',['foo','bar']).references(:value_items)

+0

Я получаю: ActiveRecord :: StatementInvalid: PG :: DatatypeMismatch: ERROR: аргумент WHERE должен быть типа boolean, а не типа записи –

+0

Пожалуйста, покажите, какой запрос вы используете, также отношения в моделях, то есть Item, Characterstics и ValueItem –

+0

Отредактированный оригинал Вопрос. –