「投稿日」でソートされたユーザーのノードとコメントの結合を取得しようとしています。この post はD6のサンドボックスプロジェクトにリンクしていますが、7には何もありません。
この post には、D6でhook_views_pre_execute()およびSQL UNIONを使用する例があります。これは、ビュー3のD7では機能しません。
Merlinofchaosに出くわした コメント
現在Drupalの新しいクエリジェネレータを使用しているため、クエリはSelectQueryオブジェクトであり、変更または置換する必要があります。詳細については、Drupal 7の新しいデータベースレイヤーを参照してください。
これを行う方法の例、または2つのビューを組み合わせる他のソリューションの例はありますか?
これが実際にテストされた例です:
/**
* Implements hook_views_pre_execute().
*/
function mymodule_views_pre_execute(view &$view) {
if ($view->name == 'my_view') {
$query1 = &$view->build_info['query'];
// Basic setup of the second query.
$query2 = db_select('another_table', 'at')
->condition('some_field', 0, '>')
->condition('some_other_field', 12345);
// The number of fields (and their aliases) must match query1.
// Get the details with:
// dpm($query1->getFields());
$query2->addField('at', 'some_field', 'alias1');
$query2->addField('at', 'some_other_field', 'alias2');
$query2->addField('at', 'some_other_field2', 'alias3');
$query2->addField('at', 'some_other_field3', 'alias4');
// Verify that queries are very similar.
// dpq($query1);
// dpq($query2);
// Matrimony.
$query1 = $query2->union($query1, 'UNION ALL');
// Manual test.
// dpm($query1->execute()->fetchAll());
}
}
これはほとんどのビューで機能します。ただし、一部のスタイルプラグインは、この手法(私が見ているカレンダーモジュール)で機能しない空想的なことを行う場合があります。
ビュー追加ハンドラーモジュールを使用して、2つの異なるビュー/ディスプレイからSQL UNIONクエリを生成できます。
Drupal.orgの詳細なチュートリアル here
最終的に、db_query()を使用してSQL UNIONを作成し、theme()関数を使用してページャーを含むテーブルレイアウトにレンダリングしました。
ユーザーにとっては、デフォルトのビューのように見えます。もう1つの利点は、クエリを大幅に最適化できることです。私は「私の友人の活動」を表示しています。そのためにビューを使用すると、友人のリストが作成され、SQLの "IN"句で使用されるため、レコード数が50または100を超えると非常に遅くなります。
友達のリストを、過去x日間にサイトにログインした友達だけに絞り込むことができます。
これはコードサンプルです:
// Two queries are required (friendships can be represented in 2 ways in the
// same table). No point making two db calls though so a UNION it is.
// Build up the first query.
$query = db_select('flag_friend', 'f')
->condition('f.uid', $account->uid)
->condition('u.login', $timestamp, '>');
$query->addExpression('f.friend_uid', 'uid');
$query->innerJoin('users', 'u', 'u.uid = f.friend_uid');
// Build up the second query.
$query2 = db_select('flag_friend', 'f')
->condition('f.friend_uid', $account->uid)
->condition('u.login', $timestamp, '>');
$query2->addExpression('f.uid', 'uid');
$query2->innerJoin('users', 'u', 'u.uid = f.uid');
// Return the results of the UNIONed queries.
return $query->union($query2)->execute()->fetchCol();
将来の参考のために、これは同じテーブルに基づいて2つのビューを組み合わせる方法です。同じ量のフィールドを持つ異なるテーブルに基づくビューにも同じ原則を適用する必要があります。
以下の例では、フォーマットがレンダリングされたエンティティに設定されているため、idのみが選択されています。ただし、フィールドを使用する場合は、以下のタイムスタンプを追加したので、フィールドが少ないクエリにダミーフィールドをいつでも追加できます。
/**
* Implements hook_views_pre_execute().
*/
function MY_MODULE_views_pre_execute(&$view) {
if ($view->name == 'VIEW_1' && $view->current_display == 'DISPLAY_OF_VIEW_1') {
$view2 = views_get_view('VIEW_2');
$view2->build('DISPLAY_OF_VIEW_2');
$view->build_info['query']
->fields('table_alias', array('timestamp'))
->union(
$view2->build_info['query']
->range()
->fields('table_alias', array('timestamp'))
->orderBy('timestamp', 'DESC')
);
$view->build_info['count_query']
->union(
$view2->build_info['count_query']
->range()
);
};
}
Views Field View というモジュールに出会いました。これにより、ビューをフィールドとして別のビューに埋め込むことができます。私自身はまだこれを試していませんが、参考になるかもしれません。
私はそれらがこれらの線に沿って何かを想像します:
/**
* Implements hook_views_pre_execute().
*/
function mymodule_views_pre_execute(&$view) {
if ($view->name == 'myview') {
$query = $view->query;
$other_view = views_get_view('otherview');
$other_query = $other_view->query;
$query = $query->union($other_query);
$view->query = $query;
}
}
私はそれをテストしていませんが。
役立ついくつかのリンク:
EntityFieldQuery Views Backend は、同時に複数のエンティティタイプのクエリをサポートします。したがって、ノードとコメントの両方のクエリに使用できるはずです。どちらのエンティティタイプもuid
プロパティを使用して作成者にリンクしているため、APIレベル EntityFieldQuery :: propertyCondition() を使用して、単一のユーザーからノードとコメントを選択できます。ビューのバックエンドが同じ機能を提供すると思います。
別のアプローチとして、ノードとコメントのfeedsを作成し(URL内のユーザーIDのコンテキストフィルターを使用)、2つのフィードを組み合わせて新しいフィードを作成し、これを投稿日ごとに表示することができます。