2016-09-02 18 views
-3

У меня есть этот запрос mysql из этого question.эквивалент DBIx :: Синтаксис класса?

SELECT a.* 
FROM products a 
INNER JOIN product_tags b ON a.product_id = b.product_id 
WHERE b.tag_id IN (1,23,54) 
GROUP BY a.product_id 
HAVING COUNT(1) = 3 

я пытаюсь выяснить, как получить это преобразуется в DBIx::Class синтаксис?

от DBIx docs, это то, что он говорит о присоединениях, но я не уверен, как его включить?

ОПРЕДЕЛЕНИЕ ПРИСОЕДИНЯЕТСЯ И ВЗАИМООТНОШЕНИЯ^

В DBIx :: Class каждое отношение между двумя таблицами необходимо сначала определить в ResultSource для таблицы. Если необходимо установить связь в обоих направлениях (т. Е. Выбрать все дорожки компакт-диска и извлечь данные CD для трека), то для обеих таблиц необходимо определить их.

Для дисков/Гусеницы пример, что означает запись в MySchema :: CD:

MySchema::CD->has_many('tracks', 'MySchema::Tracks'); 

И MySchema :: треков:

MySchema::Tracks->belongs_to('cd', 'MySchema::CD', 'CDID'); 

Есть несколько других типов отношений, они более подробно описаны в DBIx :: Class :: Relationship. ИСПОЛЬЗОВАНИЕ JOINS^

Как только вы определили все свои отношения, использование их в реальных соединениях довольно просто. Тип отношения, которое вы выбрали, например. has_many, уже указывает, какое соединение будет выполнено. Например, has_many производит LEFT JOIN, который будет извлекать все строки с левой стороны, есть ли соответствующие строки справа (таблица, соединенная с), или нет. Вы можете форсировать другие типы объединений в своих отношениях, см. Документы DBIx :: Class :: Relationship.

При выполнении либо поиска или операции поиска, вы можете указать, какие отношения также уточнить результаты, основанные на, используя атрибут соединения, как это:

$schema->resultset('CD')->search(
    { 'Title' => 'Funky CD', 
     'tracks.Name' => { like => 'T%' } 
    }, 
    { join  => 'tracks', 
     order_by => ['tracks.id'], 
    } 
); 

Если вы не признаете большинство этот синтаксис, вы, вероятно, должны прочитать «поиск» в DBIx :: Class :: ResultSet и «ATTRIBUTES» в DBIx :: Class :: ResultSet, но вот краткий прорыв:

Первый аргумент для поиска - это hashref атрибутов WHERE, в этом случае ограничение на столбец Title в таблице CD и ограничение на имя дорожки в таблице Tracks, bu t ТОЛЬКО для дорожек, фактически связанных с выбранным CD (ы). Второй аргумент - hashref атрибутов поиска, результаты будут возвращены отсортированы по идентификатору связанных дорожек.

+0

Привет, абра, есть ли у вас какие-либо предложения? вы работали с DBIx? знаете ли вы DBIx? любой из ваших друзей знает DBIx? pl показать им этот вопрос. – rajeev

+0

DBIx - это полное пространство имен, в котором DBIx :: Class является всего лишь одним модулем. Аббревиатура DBIx :: Class - это DBIC. –

ответ

2

Итак, сначала вы определили rel на тегах из продуктов.

MySchema::Result::Product->has_many(
    'tags', 'MySchema::Result::ProductTag', 'product_id' 
); 

Thne определяют отн на продукты из тегов:

MySchema::Result::ProductTag->belongs_to(
    'products', 'MySchema::Result::Product', 'product_id' 
); 

Это уже было бы сделать вывод, если вы использовали схемы :: Loader, кстати.(Shameless вилка: выше будет короче и слаще с DBIx :: Class :: Конфеты и DBIx :: Class :: Helper :: Роу :: RelationshipDWIM)

Теперь повторить исходный запрос:

$schema->resultset('Product')->search({ 
    tags.tag_id => { -in => [1,23,54] }, 
}, { 
    join => 'tags', 
    group_by => 'me.product_id', 
    having => { 'count 1' => 3 }, 
}) 
+0

принят и проголосован. thx для вашего времени и помощи Frew. Это во много раз лучше, чем многие другие администраторы сайта, которые явно не знают DBIx, но проголосовали и готовы критиковать. – rajeev