Our Application has 3 Model "Notification", "Postlike" and "Post"
In Notification Model:
public function postlike()
{
return $this->belongsTo('App\Models\PostLikes', 'postlist');
}
public function post()
{
return $this->hasMany('App\Models\PostLikes', '_id', 'c_post_id');
}
In Postlike Model:
public function postlist()
{
return $this->hasMany('App\Models\Post', '_id', 'c_post_id');
}
In Notification Repository: (Query)
public function getnotification($userId)
{
$notification = $this->makeModel()
->with('post')
->with('postlike')
->with('notification')
->orderBy('created_at' , 'desc')
->where('replied_id', $userId)
->get();
return $notification;
}
For more information we have attached following Image
enter image description here
When i firt saw your post, i thought your problem could be solved using Laravel's built-in eager loading, so it lets you do something like this:
$notification = $this->makeModel()
->with('post', 'postlike', 'postlike.postlist')
//...
->get();
If thats your case, these links shoud do the trick:
https://laracasts.com/discuss/channels/eloquent/eager-load-multiple-nested-relationships
laravel eloquent eager load multiple nested relationships
Im not sure, but it seems a little bit odd to me, that 'Notification' Model has two relations with 'Postlike' model. Maybe you should consider using some pivot table.
Hope it helps,
Notification Model :
public function postlike()
{
return $this->belongsTo('App\Models\PostLikes', 'c_post_id');
}
Query:
$notification = $this->makeModel()
{
->with('post', 'postlike', 'postlike.postlist')->get()
}
Related
I'm using many to many relationship with products and product_categories tables using product_product_category pivot table.
Product model
class Product extends Model
{
public function product_categories() {
return $this->belongsToMany(ProductCategory::class, 'product_product_category');
}
}
ProductCategory model
class ProductCategory extends Model {
public function products() {
return $this->belongsToMany(Product::class, 'product_product_category');
}
}
What I need to do is when I supply an array of categories need to get products only with these categories. This is my code
$selectedCategotries = array(1, 2);
$products = Product::with(['product_categories' => function($q) use ($selectedCategotries){
$q->whereIn('product_categories.id', $selectedCategotries);
}])->get();
But I get all the products instead. It will be a great help if you can supply a solution for me.
Finally, I found an answer with whereHas. Adding the answer for anyone who come up with the same issue.
$products = Product::whereHas('product_categories', function ($q) use ($selectedCategotries) {
$q->whereIn('product_categories.id', $selectedCategotries);
})->get();
I have two tables, 'users' and 'articles'. Articles have a column 'user_id' which is a foreign key that references the user_id in 'users'.
I have in the Articles model this function which should return the user data:
public function user()
{
return $this->belongsTo('App\User');
}
And this works fine when I pass my articles to my viewer and call it in blade template:
#foreach($articles as $article)
<p>{{$article->user->name}}</p>
#endforeach
But I am trying to use the RESTful approach, so I am rather retrieving my data from JS (VueJS)
axios.get('/api/articles')
that should fire my Controller's function:
public function index()
{
$books = bookpost::all();
return $books;
}
So I was wondering if there's a way to append the user names to the JSON array of articles before returning it because in JS I couldn't get to find a way to get the username.
You can use "eager loading" in your query to help:
$books = bookpost::with('user')->get();
You may even eager load nested relationships:
$books = bookpost::with('user.friends')->get();
Have a look at the documentation for further help.
I am learning how to do simple queries using the Yii2 framework. I use PostgreSQL.
I am trying to join two tables and get the data from both tables with a where condition.
The tables are called Admins and Persons.
The join use field called idadm.
The condition is idadm = 33. This works great but the result has data only from the Admins table and I need data from the other table.
Here is my example:
$query = \app\models\Admins::find()
->select('*')
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->all();
I am following the Yii2 official guide: http://www.yiiframework.com/doc-2.0/guide-db-active-record.html
Update: Here I show the updated code that doesn't solve de problem:
You need to write all column name in select().
$query = \app\models\Admins::find()
->select('admin.*,persons.*') // make sure same column name not there in both table
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->all();
And also you need to define person table attributes in Admin model.
Second way is get records as array,so you dont need to define attributes in Admin model.
$query = \app\models\Admins::find()
->select('admin.*,persons.*') // make sure same column name not there in both table
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->asArray()
->all();
Ensure that active record has required relations, e.g. something like follows:
class Admins extends \yii\db\ActiveRecord {
public function table() {
return "admins";
}
public function getPersons()
{
return $this->hasMany(Person::className(), ['idadm' => 'idadm']);
}
}
class Person extends \yii\db\ActiveRecord {
public function table() {
return "persons";
}
}
Then use joinWith to build query:
$query = Admins::find()
->joinWith('persons')
->limit(1);
$result = $query->createCommand()->getSql();
echo $result;
Here is produced query:
SELECT `admins`.* FROM `admins`
LEFT JOIN `person` ON `admins`.`idadm` = `person`.`idadm` LIMIT 1
I have three tables:
categories
id, title
products
id, name
categories_products
id, category_id, product_id
I have also setup the according models and relationships (both have belongsToMany of the other)
Now I want to get all products belonging to a category
Category::where('title','Electronics')->first()->products()->limit(10)->get(['products.name']);
which works fine, but I also want to include the category title for each product as well:
Category::where('title','Electronics')->first()->products()->limit(10)->get(['products.name','category.title']);
However it returns: Column not found category.title
I thought that the relation would take care of it.
EDIT: Models -->
Category:
class Category extends Model
{
protected $fillable = array('title');
public function products()
{
return $this->belongsToMany('Product', 'categories_products', 'category_id', 'product_id');
}
}
class Product extends Model
{
protected $fillable = array('name');
public function categories()
{
return $this->belongsToMany('Category', 'categories_products', 'product_id', 'category_id');
}
}
The reason you're getting the error is because get() works just like select() and because you're running the category query and then running the product query after there is no categories table to reference for the select.
Look into Eager Loading. It will help with a lot of these kinds of issues. Your query can be written as:
Product::select('id', 'name')
->with(['categories' => function($query) {
return $query->select('id', 'title');
}])
->whereHas('categories', function($query) {
return $query->where('title', 'Electronics');
})
->limit(10)
->get();
Because we are lazy loading you NEED the id column on each model so Laravel knows where to attach the relationships after the queries are run.
The with() method above will eager load the categories relationship and the whereHas() method puts a relationship constraint on the current query.
UPDATE
Similar query from Category model:
$category = Category::where('title','Electronics')
->with(['products' => function($query) {
return $query->select('id', 'name')->limit(10);
}])
->first(['id', 'title']);
Then access the products with:
$category->products
I am working with laravel 5.4. I have created countries and states table.
countries table looks like below
And my states table is :
Here, I have written join query as shown in below. It works perfect.
$state = DB::table($this->tbl_states)
->join($this->tbl_countries, $this->tbl_countries.'.id', '=', $this->tbl_states.'.country_id')
->select($this->tbl_states.'.*', $this->tbl_countries.'.name as country_name')
->whereNull($this->tbl_states.'.deleted_at')
->paginate(10)
But, Instead of writing this query I want to use Eloquent ORM so what query should I have to write?
In Country model I have create function that looks like below :
public function states()
{
return $this->hasMany('state');
}
And in State model I have write function that looks like below :
public function country()
{
return $this->hasOne('country');
}
In Country model try this:
public function states()
{
return $this->hasMany(App\State::class);
}
And in State model:
public function country()
{
return $this->belongsTo(App\Country::class);
}
And then $country->states will give you all states of this country. As well as $state->country will return state's country.
Official Docs: Eloquent: Relationships