diff --git a/docs/guide/active-record.md b/docs/guide/active-record.md
index e7ad9dc..4e9680f 100644
--- a/docs/guide/active-record.md
+++ b/docs/guide/active-record.md
@@ -838,10 +838,9 @@ use yii\db\ActiveRecord;
 
 class Comment extends ActiveRecord
 {
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-        return new CommentQuery($config);
+        return new CommentQuery(get_called_class());
     }
 }
 ```
@@ -910,10 +909,9 @@ If you used Yii 1.1 before, you may know a concept called *default scope*. A def
 applies to ALL queries. You can define a default scope easily by overriding [[yii\db\ActiveRecord::createQuery()]]. For example,
 
 ```php
-public static function createQuery($config = [])
+public static function createQuery()
 {
-    $config['modelClass'] = get_called_class();
-    return (new ActiveQuery($config))->where(['deleted' => false]);
+    return parent::createQuery()->where(['deleted' => false]);
 }
 ```
 
diff --git a/extensions/elasticsearch/ActiveQuery.php b/extensions/elasticsearch/ActiveQuery.php
index f2d9be7..662184d 100644
--- a/extensions/elasticsearch/ActiveQuery.php
+++ b/extensions/elasticsearch/ActiveQuery.php
@@ -77,6 +77,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
     use ActiveQueryTrait;
     use ActiveRelationTrait;
 
+
     /**
      * Creates a DB command that can be used to execute this query.
      * @param  Connection $db the DB connection used to create the DB command.
diff --git a/extensions/elasticsearch/ActiveRecord.php b/extensions/elasticsearch/ActiveRecord.php
index 1827651..40dc08f 100644
--- a/extensions/elasticsearch/ActiveRecord.php
+++ b/extensions/elasticsearch/ActiveRecord.php
@@ -156,23 +156,20 @@ class ActiveRecord extends BaseActiveRecord
      * You may also define default conditions that should apply to all queries unless overridden:
      *
      * ```php
-     * public static function createQuery($config = [])
+     * public static function createQuery()
      * {
-     *     return parent::createQuery($config)->where(['deleted' => false]);
+     *     return parent::createQuery()->where(['deleted' => false]);
      * }
      * ```
      *
      * Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
      * default condition. Using [[Query::where()]] will override the default condition.
      *
-     * @param  array       $config the configuration passed to the ActiveQuery class.
      * @return ActiveQuery the newly created [[ActiveQuery]] instance.
      */
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new ActiveQuery($config);
+        return new ActiveQuery(get_called_class());
     }
 
     // TODO implement copy and move as pk change is not possible
diff --git a/extensions/mongodb/ActiveRecord.php b/extensions/mongodb/ActiveRecord.php
index e60aab7..c5ed748 100644
--- a/extensions/mongodb/ActiveRecord.php
+++ b/extensions/mongodb/ActiveRecord.php
@@ -102,23 +102,20 @@ abstract class ActiveRecord extends BaseActiveRecord
      * You may also define default conditions that should apply to all queries unless overridden:
      *
      * ```php
-     * public static function createQuery($config = [])
+     * public static function createQuery()
      * {
-     *     return parent::createQuery($config)->where(['deleted' => false]);
+     *     return parent::createQuery()->where(['deleted' => false]);
      * }
      * ```
      *
      * Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
      * default condition. Using [[Query::where()]] will override the default condition.
      *
-     * @param  array       $config the configuration passed to the ActiveQuery class.
      * @return ActiveQuery the newly created [[ActiveQuery]] instance.
      */
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new ActiveQuery($config);
+        return new ActiveQuery(get_called_class());
     }
 
     /**
diff --git a/extensions/mongodb/file/ActiveRecord.php b/extensions/mongodb/file/ActiveRecord.php
index f67e815..887f0d1 100644
--- a/extensions/mongodb/file/ActiveRecord.php
+++ b/extensions/mongodb/file/ActiveRecord.php
@@ -55,23 +55,20 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord
      * You may also define default conditions that should apply to all queries unless overridden:
      *
      * ```php
-     * public static function createQuery($config = [])
+     * public static function createQuery()
      * {
-     *     return parent::createQuery($config)->where(['deleted' => false]);
+     *     return parent::createQuery()->where(['deleted' => false]);
      * }
      * ```
      *
      * Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
      * default condition. Using [[Query::where()]] will override the default condition.
      *
-     * @param  array       $config the configuration passed to the ActiveQuery class.
      * @return ActiveQuery the newly created [[ActiveQuery]] instance.
      */
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new ActiveQuery($config);
+        return new ActiveQuery(get_called_class());
     }
 
     /**
diff --git a/extensions/redis/ActiveRecord.php b/extensions/redis/ActiveRecord.php
index 77883ec..5e154b2 100644
--- a/extensions/redis/ActiveRecord.php
+++ b/extensions/redis/ActiveRecord.php
@@ -59,23 +59,20 @@ class ActiveRecord extends BaseActiveRecord
      * You may also define default conditions that should apply to all queries unless overridden:
      *
      * ```php
-     * public static function createQuery($config = [])
+     * public static function createQuery()
      * {
-     *     return parent::createQuery($config)->where(['deleted' => false]);
+     *     return parent::createQuery()->where(['deleted' => false]);
      * }
      * ```
      *
      * Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
      * default condition. Using [[Query::where()]] will override the default condition.
      *
-     * @param  array       $config the configuration passed to the ActiveQuery class.
      * @return ActiveQuery the newly created [[ActiveQuery]] instance.
      */
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new ActiveQuery($config);
+        return new ActiveQuery(get_called_class());
     }
 
     /**
diff --git a/extensions/sphinx/ActiveRecord.php b/extensions/sphinx/ActiveRecord.php
index 87efa0e..290fe19 100644
--- a/extensions/sphinx/ActiveRecord.php
+++ b/extensions/sphinx/ActiveRecord.php
@@ -146,23 +146,20 @@ abstract class ActiveRecord extends BaseActiveRecord
      * You may also define default conditions that should apply to all queries unless overridden:
      *
      * ```php
-     * public static function createQuery($config = [])
+     * public static function createQuery()
      * {
-     *     return parent::createQuery($config)->where(['deleted' => false]);
+     *     return parent::createQuery()->where(['deleted' => false]);
      * }
      * ```
      *
      * Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
      * default condition. Using [[Query::where()]] will override the default condition.
      *
-     * @param  array       $config the configuration passed to the ActiveQuery class.
      * @return ActiveQuery the newly created [[ActiveQuery]] instance.
      */
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new ActiveQuery($config);
+        return new ActiveQuery(get_called_class());
     }
 
     /**
diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md
index b4b6232..a424ee5 100644
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -234,7 +234,8 @@ Yii Framework 2 Change Log
 - Chg #2691: Null parameters will not be included in the generated URLs by `UrlManager` (gonimar, qiangxue)
 - Chg #2734: `FileCache::keyPrefix` defaults to empty string now (qiangxue)
 - Chg #2911: Removed `tbl_` default for table prefix (samdark)
-_ Chg #2912: Relative view files will be looked for under the directory containing the view currently being rendered (qiangxue)
+- Chg #2912: Relative view files will be looked for under the directory containing the view currently being rendered (qiangxue)
+- Chg #2955: Changed the signature of ActiveQuery constructors and `ActiveRecord::createQuery()` to simplify customizing ActiveQuery classes (qiangxue)
 - Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue)
 - Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue)
 - Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue)
diff --git a/framework/db/ActiveQueryTrait.php b/framework/db/ActiveQueryTrait.php
index abc0728..6c423e3 100644
--- a/framework/db/ActiveQueryTrait.php
+++ b/framework/db/ActiveQueryTrait.php
@@ -32,6 +32,17 @@ trait ActiveQueryTrait
 
 
     /**
+     * Constructor.
+     * @param array $modelClass the model class associated with this query
+     * @param array $config configurations to be applied to the newly created query object
+     */
+    public function __construct($modelClass, $config = [])
+    {
+        $this->modelClass = $modelClass;
+        parent::__construct($config);
+    }
+
+    /**
      * Sets the [[asArray]] property.
      * @param boolean $value whether to return the query results in terms of arrays instead of Active Records.
      * @return static the query object itself
diff --git a/framework/db/ActiveRecord.php b/framework/db/ActiveRecord.php
index 324ab1b..26c4a8a 100644
--- a/framework/db/ActiveRecord.php
+++ b/framework/db/ActiveRecord.php
@@ -234,23 +234,20 @@ class ActiveRecord extends BaseActiveRecord
      * You may also define default conditions that should apply to all queries unless overridden:
      *
      * ```php
-     * public static function createQuery($config = [])
+     * public static function createQuery()
      * {
-     *     return parent::createQuery($config)->where(['deleted' => false]);
+     *     return parent::createQuery()->where(['deleted' => false]);
      * }
      * ```
      *
      * Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
      * default condition. Using [[Query::where()]] will override the default condition.
      *
-     * @param array $config the configuration passed to the ActiveQuery class.
      * @return ActiveQuery the newly created [[ActiveQuery]] instance.
      */
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new ActiveQuery($config);
+        return new ActiveQuery(get_called_class());
     }
 
     /**
diff --git a/framework/db/ActiveRecordInterface.php b/framework/db/ActiveRecordInterface.php
index 15a58c4..8418581 100644
--- a/framework/db/ActiveRecordInterface.php
+++ b/framework/db/ActiveRecordInterface.php
@@ -155,19 +155,18 @@ interface ActiveRecordInterface
      * You may also define default conditions that should apply to all queries unless overridden:
      *
      * ```php
-     * public static function createQuery($config = [])
+     * public static function createQuery()
      * {
-     *     return parent::createQuery($config)->where(['deleted' => false]);
+     *     return parent::createQuery()->where(['deleted' => false]);
      * }
      * ```
      *
      * Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
      * default condition. Using [[Query::where()]] will override the default condition.
      *
-     * @param array $config the configuration passed to the ActiveQuery class.
      * @return ActiveQueryInterface the newly created [[ActiveQueryInterface|ActiveQuery]] instance.
      */
-    public static function createQuery($config = []);
+    public static function createQuery();
 
     /**
      * Updates records using the provided attribute values and conditions.
diff --git a/framework/db/BaseActiveRecord.php b/framework/db/BaseActiveRecord.php
index 0b4ab38..e041086 100644
--- a/framework/db/BaseActiveRecord.php
+++ b/framework/db/BaseActiveRecord.php
@@ -309,13 +309,12 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
     public function hasOne($class, $link)
     {
         /** @var ActiveRecordInterface $class */
-
-        return $class::createQuery([
-            'modelClass' => $class,
-            'primaryModel' => $this,
-            'link' => $link,
-            'multiple' => false,
-        ]);
+        /** @var ActiveQuery $query */
+        $query = $class::createQuery();
+        $query->primaryModel = $this;
+        $query->link = $link;
+        $query->multiple = false;
+        return $query;
     }
 
     /**
@@ -351,13 +350,12 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
     public function hasMany($class, $link)
     {
         /** @var ActiveRecordInterface $class */
-
-        return $class::createQuery([
-            'modelClass' => $class,
-            'primaryModel' => $this,
-            'link' => $link,
-            'multiple' => true,
-        ]);
+        /** @var ActiveQuery $query */
+        $query = $class::createQuery();
+        $query->primaryModel = $this;
+        $query->link = $link;
+        $query->multiple = true;
+        return $query;
     }
 
     /**
diff --git a/framework/web/ContentTypeNegotiator.php b/framework/web/ContentTypeNegotiator.php
new file mode 100644
index 0000000..51fa090
--- /dev/null
+++ b/framework/web/ContentTypeNegotiator.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright (c) 2008 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+namespace yii\web;
+
+use yii\base\Component;
+
+/**
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @since 2.0
+ */
+class ContentTypeNegotiator extends Component
+{
+    /**
+     * @var array list of supported API version numbers. If the current request does not specify a version
+     * number, the first element will be used as the [[version|chosen version number]]. For this reason, you should
+     * put the latest version number at the first. If this property is empty, [[version]] will not be set.
+     */
+    public $supportedVersions = [];
+    /**
+     * @var array list of supported response formats. The array keys are the requested content MIME types,
+     * and the array values are the corresponding response formats. The first element will be used
+     * as the response format if the current request does not specify a content type.
+     */
+    public $supportedFormats = [
+        'application/json' => Response::FORMAT_JSON,
+        'application/xml' => Response::FORMAT_XML,
+    ];
+
+}
diff --git a/tests/unit/data/ar/Customer.php b/tests/unit/data/ar/Customer.php
index 79f4c1a..855a4b8 100644
--- a/tests/unit/data/ar/Customer.php
+++ b/tests/unit/data/ar/Customer.php
@@ -62,10 +62,8 @@ class Customer extends ActiveRecord
         parent::afterSave($insert);
     }
 
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new CustomerQuery($config);
+        return new CustomerQuery(get_called_class());
     }
 }
diff --git a/tests/unit/data/ar/elasticsearch/Customer.php b/tests/unit/data/ar/elasticsearch/Customer.php
index 6f058a5..61c1856 100644
--- a/tests/unit/data/ar/elasticsearch/Customer.php
+++ b/tests/unit/data/ar/elasticsearch/Customer.php
@@ -64,10 +64,8 @@ class Customer extends ActiveRecord
 
     }
 
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new CustomerQuery($config);
+        return new CustomerQuery(get_called_class());
     }
 }
diff --git a/tests/unit/data/ar/mongodb/Customer.php b/tests/unit/data/ar/mongodb/Customer.php
index 268d931..98cf41f 100644
--- a/tests/unit/data/ar/mongodb/Customer.php
+++ b/tests/unit/data/ar/mongodb/Customer.php
@@ -25,10 +25,8 @@ class Customer extends ActiveRecord
         return $this->hasMany(CustomerOrder::className(), ['customer_id' => '_id']);
     }
 
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new CustomerQuery($config);
+        return new CustomerQuery(get_called_class());
     }
 }
diff --git a/tests/unit/data/ar/mongodb/file/CustomerFile.php b/tests/unit/data/ar/mongodb/file/CustomerFile.php
index f3be658..6c97b37 100644
--- a/tests/unit/data/ar/mongodb/file/CustomerFile.php
+++ b/tests/unit/data/ar/mongodb/file/CustomerFile.php
@@ -20,10 +20,8 @@ class CustomerFile extends ActiveRecord
         );
     }
 
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new CustomerFileQuery($config);
+        return new CustomerFileQuery(get_called_class());
     }
 }
diff --git a/tests/unit/data/ar/redis/Customer.php b/tests/unit/data/ar/redis/Customer.php
index 637cea6..60c1983 100644
--- a/tests/unit/data/ar/redis/Customer.php
+++ b/tests/unit/data/ar/redis/Customer.php
@@ -31,10 +31,8 @@ class Customer extends ActiveRecord
         parent::afterSave($insert);
     }
 
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new CustomerQuery($config);
+        return new CustomerQuery(get_called_class());
     }
 }
diff --git a/tests/unit/data/ar/sphinx/ArticleIndex.php b/tests/unit/data/ar/sphinx/ArticleIndex.php
index 916ddaf..742d2d4 100644
--- a/tests/unit/data/ar/sphinx/ArticleIndex.php
+++ b/tests/unit/data/ar/sphinx/ArticleIndex.php
@@ -25,10 +25,8 @@ class ArticleIndex extends ActiveRecord
         return $this->source->content;
     }
 
-    public static function createQuery($config = [])
+    public static function createQuery()
     {
-        $config['modelClass'] = get_called_class();
-
-        return new ArticleIndexQuery($config);
+        return new ArticleIndexQuery(get_called_class());
     }
 }