LoginSignup
1
1

More than 5 years have passed since last update.

Viewsで生成されるSQLにロジックでLEFT JOINしてみる

Last updated at Posted at 2016-03-29

Viewsは便利ですが、ロジックでごにょごにょできると、
より一層便利で

hook_views_query_alter を使います。
views_join についてはこちらを参照。
add_relationshipについてはこちらを参照。

/**
 * Implementation of hook_views_query_alter().
 */
function MYMODULE_views_query_alter(&$view, &$query) {

    // do something.

    $join = new views_join();
    $join->table = 'field_data_field_hoge';
    $join->field = 'entity_id';
    $join->left_table = 'node';
    $join->left_field = 'nid';
    $join->type = 'left';

    $query->add_relationship('field_hoge', $join, 'node');

    // 以下はおまけ
    $query->where[1]['conditions'][] = array(
        'field' => 'field_hoge.bundle',
        'value' => array('content_type_A', 'content_type_B'),
        'operator' => 'IN'
    );
}

すると、以下のSQLになる。

SELECT
  -- 省略
FROM
  node node 
  LEFT JOIN field_data_field_hoge field_hoge 
    ON node.nid = field_hoge.entity_id
WHERE
  field_hoge.bundle IN ('contents_type_A', 'contents_type_B')

ちなみに、画面からの検索キーワードでライクしてみる。

$word = '%' . filter_xss($view->exposed_input['search_word']) . '%';

$or_condition = db_or();
$or_condition->condition('node.title', $word, 'ILIKE'); // ILIKE はPostgreSQLの方言
$query->add_where(1, $or_condition);

すると

SELECT
  -- 省略
FROM
  node node 
  LEFT JOIN field_data_field_hoge field_hoge
    ON node.nid = field_hoge.entity_id
WHERE
  field_hoge.bundle IN ('content_type_A', 'content_type_B')
  AND node.title ILIKE '%neko%'

無事にライクできる。

備考

$view->exposed_input の値ってサニタイズされるんじゃなかったでしたっけ?
自前でViewsの検索条件として画面項目を追加した際の設定漏れなのかな。。
わざわざ filter_xss や check_plain はしなくてよかったハズ。
(´-`).。oO(あとで調べる)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1