I Have
Worker -> HasOne-> Document ->morphMany ->FIles
->HasOne-> Medical ->morphMany ->FIles
->HasOne-> Course ->morphMany ->FIles
I want to use hasManyTrough to get files data from worker, I defined
public function medical_detail()
{
return $this->hasOne(MedicalDetail::class);
}
Tried this :
public function document_files()
{
return $this->hasManyThrough(File::class, Document::class);
}
In worker but It expects document_id, how can I use ir for polymirhic relationship?
Also did this
public function document_files()
{
return $this->hasManyThrough(
File::class,
Document::class,
'worker_id',
'filable_id',
'id',
'id'
);
}
THese are my models
File model
protected $fillable = ['file_type', 'file_name', 'fiable_id', 'filable_type'];
public function filable()
{
return $this->morphTo();
}
Worker MOdel
public function course()
{
return $this->hasOne(Course::class);
}
public function document()
{
return $this->hasOne(Document::class);
}
Document model
protected $fillable = ['doc_name', 'worker_id'];
public function worker()
{
return $this->belongsTo(Worker::class);
}
public function files()
{
return $this->morphMany(File::class, 'filable');
}
This is one alternative I added, but gives me No query results for model [App\\Models\\Worker] 1 . SInce files table has $table->morphs('filable'); This defined so I added filable_id. These are my models: docuemnt,file
Related
I'm trying to display which one attribute (code) of Item. ServiceItem has Item as a foreign key. But I can't get the Item at all.
This one gives a blank object in blade template:
#foreach ($service->serviceItems as $serviceItem )
{{ json_encode($serviceItem->item()) }}
#endforeach
Here's my model declaration:
//ServiceItem model
class ServiceItem extends Model
{
use HasFactory;
public $fillable = ['service_id', 'item_id', 'values'];
public function service()
{
return $this->belongsTo(Service::class, 'foreign_key');
}
// this doesn't work
public function item()
{
return $this->belongsTo(Item::class, 'foreign_key');
}
}
// Service model
class Service extends Model
{
use HasFactory;
public $fillable = ['user_id', 'site_id', 'title', 'status', 'remarks', 'report', 'date'];
public function user()
{
return $this->belongsTo('\App\Models\User');
}
public function site()
{
return $this->belongsTo('\App\Models\Site');
}
public function serviceItems() {
return $this->hasMany('\App\Models\ServiceItem');
}
}
This is my controller:
public function index()
{
$services = Service::latest()->paginate(5);
return view('services.index', compact('services'))
->with('i', (request()->input('page', 1) - 1) * 5);
}
Please help me to display the code attribute in Item from Service!!! Thanks a lot!
I suppose you read the Laravel doc of model relationship definition. They referenced to put foreign key as the second parameter, not the foreign_key as word but your actual foreign key that reference the parent table. you have to change the model code.
class ServiceItem extends Model
{
use HasFactory;
public $fillable = ['service_id', 'item_id', 'values'];
public function service()
{
return $this->belongsTo(Service::class, 'service_id');
}
public function item()
{
return $this->belongsTo(Item::class, 'item_id');
}
}
and then $serviceItem->item should work as expected.
I have a 3 model "User","Review","ReviewReplay"
in user Model
public function reviews()
{
return $this->hasMany('App\Models\Review');
}
public function reviewReplys()
{
return $this->hasMany('App\Models\ReviewReply');
}
In Review Model
public function user()
{
return $this->belongsTo('App\Models\User');
}
public function reviewReplys()
{
return $this->hasMany('App\Models\ReviewReply');
}
in Review Replay Model
public function user()
{
return $this->belongsTo('App\Models\User');
}
public function review()
{
return $this->belongsTo('App\Models\Reviews');
}
in My Controller
public function getReview($id)
{
$review= Review::where('product_id',$id)->with('user','reviewReplys')->paginate(10);
return response()->json($review);
}
Now here I run Review foreach loop and here I need review.reviewReplay.user information. How I Get The Review Replay User information inside Review Foreach loop.
You can do it as below.
$review= Review::where('product_id',$id)->with(['reviewReplys.user'])->paginate(10);
with(['reviewReplys.user']) --> it will make connection between Review model to reviewReplys model +
reviewReplys model to User model
There is a model Invoice which equals to a purchase basket and model InvoiceItem which stores items inside a specific invoice. The model invoice has status field, if its value is 2999 and someone has verified it, it is successful. I need to get invoice items which are sold. Here is codes:
class Invoice extends Model
{
protected $fillable = [];
protected $table = 'payment_invoices';
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function scopeSuccessful($query)
{
return $query->where('status', 2999)->where('verified_at', '<>', null);
}
}
and
class InvoiceItem extends Model
{
protected $fillable = [];
protected $table = 'payment_invoice_items';
public function invoice()
{
return $this->belongsTo(Invoice::class, 'invoice_id');
}
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function vendor()
{
return $this->belongsTo(Vendor::class, 'vendor_id');
}
public function scopeNotDeleted($query)
{
return $query->where('deleted_at', null);
}
public function scopeSold($query)
{
return $query->notDeleted()->whereHas('invoice', function ($q) {
$q->successful();
});
}
}
The following statement
InvoiceItem::sold()->take(10)->get()
returns 10 sold items but it is very slow. it takes about 4 seconds to retrieve the information while the query
select *
from laravel.payment_invoice_items pii
join laravel.payment_invoices pi
on pi.id = pii.invoice_id
and pii.deleted_at isnull
and pi.status=2999
and pi.verified_at notnull
limit 10
takes about 800 milliseconds. Eloquent is very inefficient. Is there any solution to use the eloquent and get the same efficiency here?
I would like to get the model relations, in array;
My model look like:
class User extends Model
{
public function profile() {
return $this->haOne(Profile::class);
}
public function settings() {
return $this->morphOne(Settings::class, 'settingsable');
}
public function addresses() {
return $this->hasMany(Addresses::class);
}
}
And my code:
$user = User::with(['profile', 'settings', 'addresses'])->find(1);
$user->getRelations(); // return ['profile', 'settings', 'addresses'];
If I have more then 10 relation, I don't want to list all.
I would like to get like this:
$relations = ['profile', 'settings', 'addresses'];
Is this posible?
You could try adding a scope to the model, and so, you have to only write them once.
class User extends Model
{
public function profile() {
return $this->haOne(Profile::class);
}
public function settings() {
return $this->morphOne(Settings::class, 'settingsable');
}
public function addresses() {
return $this->hasMany(Addresses::class);
}
public function scopeWithRelations(Builder $query){
return $query->with([...]);
}
}
$users = User::withRelations()->get();
This way you only have to write them once there, and everywhere in the code you'll use the scope.
Not exactly 100% what you're asking, but this could be a solution.
I have a problem with a many to many relationship and the translations of the terms.
I have 4 tables:
products
- id, price, whatever
products_lang
- id, product_id, lang, product_name
accessori
- id, active
accessori_lang
- id, accessori_id, lang, accessori_name
I'm trying to assign accessories to products with an intermediate table named:
accessori_products
this is the model for Product:
class Product extends Model {
protected $table = 'products';
public function productsLang () {
return $this->hasMany('App\ProductLng', 'products_id')->where('lang','=',App::getLocale());
}
public function productsLangAll() {
return $this->hasMany('App\ProductLng', 'products_id');
}
public function accessori() {
return $this->belongsToMany('App\Accessori', 'accessori_products');
}
}
this is the model for productLng:
class ProductLng extends Model {
protected $table = 'products_lng';
public function products() {
return $this->belongsTo('App\Product', 'products_id', 'id');
}
}
Then I have the model for Accessori:
class Accessori extends Model {
protected $table = 'accessori';
public function accessoriLang() {
return $this->hasMany('App\AccessoriLng')->where('lang','=',App::getLocale());
}
public function accessoriLangAll() {
return $this->hasMany('App\AccessoriLng');
}
public function accessoriProducts() {
return $this->belongsToMany('App\Products', 'accessori_products', 'accessori_id', 'products_id');
}
}
And the model for AccessoriLng:
class accessoriLng extends Model {
protected $table = 'accessori_lng';
public function accessori() {
return $this->belongsTo('App\Accessori', 'accessori_id', 'id');
}
}
the last model is for the relationship between the two tables above:
class ProductAccessori extends Model {
protected $table = 'accessori_products';
public function accessoriProducts() {
return $this->belongsTo('App\Product', 'accessori_id', 'products_id');
}
}
I'm trying to get the accessories of each product and to get also the translation but I'm having a lot of problem with this.
It's my first time with a many to many relation with translations too.
Can anyone put me on the right direction?
controller
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
you'll get products with accessori that has accessoriLang.