Add custom column to identify table during query - laravel

How can I add a custom column in an Eloquent select query in order to identify the table?
For example, I have the current query:
$posts = Post::where('user_id', getUserID())
->get();
I'd like to add a column is_post with value 1 (for true) during the query.
The Post class:
<?php
class Post extends Eloquent {
protected $table = 'posts';
}
How can I do this?

You could do it for example this way:
$posts = Post::where('user_id', getUserID())->selectRaw('*, 1 AS `is_post`')->get();
but depending on your needs, you can also use the piece of code you showed:
$posts = Post::where('user_id', getUserID())->get();
and add accessor in Post model this way:
public function getIsPostAttribute($value) {
return 1;
}
In both cases you should be able to display is_post value for example this way:
foreach ($posts as $post) {
echo $post->is_post;
}

Related

laravel multiple relation query

I have 3 model in my project and i want to get a query or collection result as i say:
JewelsItem model:
protected $table = 'jewel_items';
public function jewel(){
return $this->belongsTo('App\Models\Jewel');
}
public function sellInvoice(){
return $this->belongsTo(SellInvoice::class,'sell_invoice_id');
}
2.Jewel model:
public function jewelsItems(){
return $this->hasMany('App\Models\JewelsItem');
}
3.sellInvoice model:
protected $table = "sell_invoices";
public function jewelsItems(){
return $this->hasMany(JewelsItem::class,'buy_invoice_id');
}
Query: i want to get all jewelsitems that has no sellInvoice and has jewel name like 'something'.
note: jewel model has a name attribute .and i want to add name of jewel to first of all the collection's items of result.
i know how to get all jewel with name of 'something' :
Jewel::where('name','like','something'.'%')->get();
but i can't get all jewelItem related to it an add name of jewel to first of them.
To look for condition in another relationship you can use whereHas() and whereDoesntHave()
$name = 'something';
$items = JewelsItem::whereHas('jewel', function($query) use ($name) {
$query->where('name', 'LIKE', "%{$name}%");
})
->whereDoesntHave('sellInvoice')
->with('jewel')
->get();
It reads: getting jewel items where jewel has $name in the name field
and doesn't have sell invoice
then add related jewel to the jewel item.
When you want to retrieve the name of the jewel, you can access its property like so.
foreach($items as $item) {
echo $item->jewel->name;
}

mb_strpos() expects parameter 1 to be string, object given when querying 2 tables in Laravel

Ok, so I don't know if this can be done, but I need to combine the results of 2 Where clauses from 2 tables into one variable.
So far I have this working to query one table:
$allCompanies = Products::where('category_id', $id->id)->groupBy('company_id')->get();
And this for the other:
$companies = Company::where('visible', 0)->get();
But is there any way to get them into the same query string? Something like so I can get where the ID matches the ID column in one table AND where visible is 0 in the other?
I tried this:
$allCompanies = Products::with('company', function($q){
$q->where('visible', 0);
})->where('category_id', $id->id)
->groupBy('company_id')->get();
but got this error:
mb_strpos() expects parameter 1 to be string, object given
Company Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
public function products()
{
return $this->hasMany('App\Products');
}
}
Products Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Products extends Model
{
protected $fillable = [
'name',
'description',
'image',
'size',
'price',
'stock',
'company_id',
'category_id'
];
public function category()
{
return $this->belongsTo('App\Categories', 'category_id');
}
public function company()
{
return $this->belongsTo('App\Company', 'company_id');
}
}
When using callback in with, you should pass callback as value of associative-array.
Your query should be:
$allCompanies = Products::with(['company' => function($q) {
$q->where('visible', 0);
}])
->where('category_id', $id->id)
->groupBy('company_id')
->get();
Ref: https://laravel.com/docs/8.x/eloquent-relationships#nested-eager-loading-morphto-relationships
The most Laravel way of achieving this is through Relationships and whereHas. If you have a relationship defined you could do the following:
$products = Products::where('category_id', $id->id)
->whereHas('company', function($q) {
$q->where('visible', 0);
});
Which will query for all the products with a certain category_id that also have a relationship with a company that has a column visible with value 0
Depends on what you want:
If you want all the products from visible companies:
$products = Products::whereHas('company', function($q) {
$q->where('visible',0);
})->get();
If you want all the companies with their products (which I would advise):
$Companies = Company::with('products')->where('visible',0)->get();

Filter on related table with Laravel and eloquent

My method is:
public function show(Tag $tag)
{
$posts = $tag->posts;
return view('posts.index',compact('posts'));
}
It works fine but i want to get the posts where posts->user_id is the authenticated user.
public function show(Tag $tag)
{
$posts = $tag->posts()->where('user_id',Auth::user()->id);
return view('posts.index',compact('posts'));
}
How do i filter on the related posts table?
this is a many to many relationship with a pivot table present
What you have should work, but don't forget to get() the results after adding your where:
$posts = $tag->posts()->where('user_id',Auth::user()->id)->get();

Laravel 4 unable to retrieve value from belongsTo relation using query builder

I have two tables, organizations and categories. This is how my tables and models are set up:
Tables:
organizations
id - integer
category_id - integer, fk
name - string
...
categories
id - integer
name - string
Models:
class Organization extends Eloquent
{
public function category()
{
return $this->belongsTo('Category');
}
public function comments()
{
return $this->morphMany('Comment', 'commentable');
}
}
class Category extends Eloquent
{
public $timestamps = false;
public function organization()
{
return $this->hasMany('Organization');
}
}
In my routes.php file, I have the following code (where $category is equal to "organizations"):
$query = Organization::query()
->join('categories', 'categories.id', '=', $category . '.id')
->select('categories.name as category');
$tiles = $query->get();
In my view, I am able to perform the following actions without any errors:
foreach($tile->comments as $comment)
{
...
}
...
$tile->name;
However, calling $tile->category->name will give me the error Trying to get property of non-object. And calling $tile->category will just return null. How can I display the category associated with the organization? I am able to retrieve other properties and relations just fine, but this is giving me a problem.
You have a bug in your code: $category . '.id' should be $category . '.category_id' doing so should make $tile->category->name work.
Also please note (you probably already know this) that in the code that you provided you are not actually using the belongsTo relation as set in your Organization class, you are just using the joined data.
The following would also work using the Eloquent ORM utilizing the models relationship methods:
$tiles = Organization::with('category')
->get();
foreach ($tiles as $tile)
{
echo $tile->name . '<br>';
echo $tile->category->name . '<br>';
}
Or you could do so the other way round from the categories model like so:
$tiles = Category::with('organization')
->get();
foreach ($tiles as $tile)
{
echo $tile->name . '<br>';
foreach($tile->organization as $org)
{
echo $org->name . '<br>';
}
}

Eloquent where condition based on a "belongs to" relationship

Let's say I have the following model:
class Movie extends Eloquent
{
public function director()
{
return $this->belongsTo('Director');
}
}
Now I'd like fetch movies using a where condition that's based on a column from the directors table.
Is there a way to achieve this? Couldn't find any documentation on conditions based on a belongs to relationship.
You may try this (Check Querying Relations on Laravel website):
$movies = Movie::whereHas('director', function($q) {
$q->where('name', 'great');
})->get();
Also if you reverse the query like:
$directorsWithMovies = Director::with('movies')->where('name', 'great')->get();
// Access the movies collection
$movies = $directorsWithMovies->movies;
For this you need to declare a hasmany relationship in your Director model:
public function movies()
{
return $this->hasMany('Movie');
}
If you want to pass a variable into function($q) { //$variable } then
function($q) use ($variable) { //$variable }
whereBelongsTo()
For new versions of Laravel you can use whereBelongsTo().
It will look something like this:
$director = Director::find(1);
$movies = Movie::whereBelongsTo($director);
More in the docs.
is()
For one-to-one relations is() can be used.
$director = Director::find(1);
$movie = Movie::find(1);
$movie->director()->is($director);

Resources