New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AR relation scope #1579
Comments
See updated doc: 65d72eb I don't think we should drop the |
i dont like to write manually each time, its like writing |
Also is that a bug $model = Users::find()->with([
'SomeOtherUsers' => function($q){
$q->byId(2); #->limit(10)->orderBy('user_id')
},
])->one(); //all() when i query like this i got in debugger info:
and in /**
* @return \yii\db\ActiveRelation
*/
public function getSomeOtherUsers()
{
return $this->hasMany(SomeOtherUsers::className(), ['user_id' => 'id']);
} And in the opposite AR: /**
* @return \yii\db\ActiveRelation
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
public static function byId($query,$id)
{
$query->andWhere('id = :id',[':id' => intval($id)]);
} Even when i change id in query, for example to 3 i got sql:
but still all rows a quired from related table and in $model->SomeOtherUsers i got all models like there were no conditions. |
Queries generated look a bit suspicious... |
Was testing this on Windows 7 / php 5.4 / postgresql 9.3 on
use yii\db\Schema;
class m131219_152916_tbl_some_other_user extends \yii\db\Migration
{
public function safeUp()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
}
$this->createTable('some_other_user', [
'id' => Schema::TYPE_PK,
'user_id' => Schema::TYPE_INTEGER. ' NOT NULL',
'attribute_key' => Schema::TYPE_STRING . '(32) NOT NULL',
], $tableOptions);
$this->addForeignKey('some_other_user_users_fk','some_other_user','user_id','tbl_user','id');
}
public function safeDown()
{
$this->dropTable('some_other_user');
}
} |
It's not quite clear to me what the problem is. What are the query statement and what are the corresponding SQLs (you listed three, but there should only be two)? |
the problem is that when i query with relation and apply some scopes/limits to relations they are dont apply (and query all rows from related table), looks like. And yes i dont know why it generates 3 queries (they are taken from debug) instead of 2. You can this on basic boilerplate, there is an info about migrations for tables and relations. |
The call stack line number for the three SQL statements are different. Are you sure they are all for the same query statement? |
yes, my controller only have this (modified it a little since was posted here, but issue is still the same): <?php
namespace app\controllers;
use Yii;
use yii\web\AccessControl;
use yii\web\Controller;
use yii\web\VerbFilter;
use app\models\LoginForm;
use app\models\ContactForm;
use app\models\Users;
class SiteController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
public function actionIndex()
{
$model = Users::find()->with([
'SomeOtherUsers' => function($q){
$q->byId(3); #->limit(10)->orderBy('user_id')
},
])
->where('id=:id',[':id' => 1])
->one();
#var_dump($model);
#print_r($model->attributes);
print_r($model->someOtherUsers);
#exit();
return $this->render('index');
}
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
$this->goHome();
}
$model = new LoginForm();
if ($model->load($_POST) && $model->login()) {
return $this->goBack();
} else {
return $this->render('login', [
'model' => $model,
]);
}
}
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
public function actionContact()
{
$model = new ContactForm;
if ($model->load($_POST) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted');
return $this->refresh();
} else {
return $this->render('contact', [
'model' => $model,
]);
}
}
public function actionAbout()
{
return $this->render('about');
}
} |
Try changing |
worked like a charm :D yeah, i think this should be documented or maybe somehow fixed in code. Also when generating AR i got error in relation i got
not in plural mode, i think this is because of Yii2 only stands for single AR names. But info about scope name is not documented/fixed anywhere. |
also looks like if i try to get parent relation it quires new sql, i think this should be fixed: var_dump($model->someOtherUsers[0]->user->attributes == $model->attributes);
|
Yes, this needs to be fixed in Yii by throwing an exception.
This is expected due to limited knowledge of Gii in this case. You need to fix it manually.
This is also expected. By no means Yii will attempt to populate parent relation when you don't request for it. |
but maybe we can set it when parent is invoked with its child (or it is not needed because of cycle references)? |
The parent and child relations could be defined differently. @cebe Do you still remember why we require relation names to be case sensitive? It used to be case insensitive. |
@klimov-paul Thanks. Looking through #1125, I still don't remember why we should make relation names case sensitive. To fix this issue, if we keep relation names to be case sensitive, then we need to use method reflection to detect case sensitivity problem in places such as |
I remember we did it becaue |
I see. It's because of |
In Yii1 i can write following code and it will work:
Main idea is that i can chain scopes and apply conditions in the way how i want it to be. In Yii2 its not working, i got
in ActiveQueryTrait.php:196 line. I think we should keep feature of Yii1 when in with() for some relations i can set what scopes/limit/order should be bound with this relation. Or show how to do it correctly without losing this features? Example in the guide with
is awful. I also suggest to exclude
$query
from params list and make itself::getQuery()
if it is possible.The text was updated successfully, but these errors were encountered: