Reputation: 51
I built a website with Yii2 and I tried to get the records which their categories are available. I have got the available categories and stored them in an array. But it returns nothing when I tried to use the 'in' condition for the next query. I am sure that the database records are correct.
// Get active categories
$active_cat = Category::find()
->where(['status' => SystemCode::STATUS_ACTIVE])
->andwhere(['is_deleted' => 0])
->select(['id'])
->asArray()
->all();
// Get available articles
$query = Articles::find()
->where(['in', 'cat_id', $active_cat]);
Upvotes: 3
Views: 6327
Reputation: 22174
You're using all()
to get list of categories, which will give you array of rows in format:
[
['id' => 1],
// ...
],
But for your next query you need a flat list of IDs - you can achieve this by using column()
method instead:
// Get active categories
$active_cat = Category::find()
->where(['status' => SystemCode::STATUS_ACTIVE])
->andWhere(['is_deleted' => 0])
->select(['id'])
->column();
// Get available articles
$query = Articles::find()
->where(['in', 'cat_id', $active_cat]);
Upvotes: 3
Reputation: 1105
Please note the return value of each method:
one() This method returns an ActiveRecord object or null if not found.
one() Executes query and returns a single row of result.
all() This method returns a list of ActiveRecord objects or an empty array if not found
all() Executes the query and returns all results as an array. So in the
all()
method:foreach($active_cat as $cat){ # code... }
Here, of course, you can access the second table by "Relational Data"
asArray() Whether to return the query results in terms of arrays instead of Active Records.
Also:
yii\db\ActiveRecord::findOne(): returns a single Active Record instance populated with the first row of the query result. (Returns a single active record model instance by a primary key or an array of column value)
yii\db\ActiveRecord::findAll(): returns an array of Active Record instances populated with all query result. (a list of active record models that match the specified primary key value(s) or a set of column values.)
Upvotes: 0
Reputation: 2705
Assuming that you have a one-to-many relation between Articles
and Category
defined as follows:
/**
* @return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(Category::class, ['id' => 'cat_id']);
}
You can get all Articles
records where status = SYSTEM_CODE::STATUS_ACTIVE
like this:
$articles = $query = Articles::find()->joinWith('category')
->where([
'category.status' => SYSTEM_CODE::STATUS_ACTIVE,
'category.is_deleted' => 0
])->all();
If, instead the relation is many-to-many, and it is defined like this:
/**
* @return \yii\db\ActiveQuery
*/
public function getCategories()
{
return $this->hasMany(
Category::className(),
['id' => 'cat_id'])->viaTable(
'article_category', ['article_id' => 'id']
);
}
Then you can get the same result like this:
$articles = $query = Articles::find()->joinWith('categories')
->where([
'category.status' => SYSTEM_CODE::STATUS_ACTIVE,
'category.is_deleted' => 0
])->all();
Only the name of the relation changes in the second example.
Note that I have made a few assumptions, like the name of the category
table being category
, a junction table being called article_category
and so on, you may have to modify the examples to fit your code.
The documentation for joinWith().
Upvotes: 0
Reputation: 3507
Here is how you can do: You have to reorganize your code: in Categories model you have to put this function:
public function getActiveArticles()
{
return $this=->hasMany(Articles::classname(), ['cat_id' => 'id'])->andWhere(['categories_table.status' => SystemCode::STATUS_ACTIVE, 'categories_table.is_deleted' => 0]);
}
Now you can access all articles by:
$active_cat = Category::find()->all();
foreach($active_cat as $cat)
{
if($cat->activeAcrticles !== null)
{
foreach($cat->activeAcrticles as $article)
{
echo $article->name;
}
}
}
Upvotes: -1