laravel relation data to search for other models - laravel

Client model has relations to Invoice. I need to get the amounts from the Invoice relationship and find the matching transactions from the Transaction model.
I do it like this:
class Client extends Model
{
public function invoices()
{
return $this->hasMany(Invoice::class);
}
public function priceInvoices()
{
return $this->hasMany(Invoice::class)->select('gross_price');
}
}
foreach (Client::find($id)->priceInvoices->toArray() as $item) {
$prices[] = $item['gross_price'];
}
$transactions_for_prices = Transaction::whereIn('price', $prices)->get();
Will it be possible to make it more elegant?

If your Invoice.php Model has a relationship with a Transaction.php Model,
Example:
class Invoice extends Model
{
public function trasnactions()
{
return $this->hasMany(Transaction::class);
}
}
You could do something like this in a controller. (example)
public function show($id) {
$client = Client::findOrFail($id);
return view('view_name', [
'client' => $client,
'transactions => $client->invoices->transactions
]);
}

Related

Laravel How To Update Nested createMany

Been having a hard time on figuring out how to implement updating records on a nested createMany based on the store method. I have these models and relations:
User Model:
class User extends Model
{
public function orders() {
return $this->hasMany(Order::class);
}
}
Order Model:
class Order extends Model
{
public function user() {
return $this->belongsTo(User::class);
}
public function subOrders() {
return $this->hasMany(SubOrder::class);
}
}
SubOrder Model:
class SubOrder extends Model
{
public function order() {
return $this->belongsTo(Order::class);
}
public function subOrderProducts() {
return $this->hasMany(SubOrderProducts::class);
}
}
SubOrderProducts Model:
class SubOrderProducts extends Model
{
public function subOrder() {
return $this->belongsTo(SubOrder::class);
}
}
Here are the tables:
orders table:
id name
sub_orders table:
id order_id date price
sub_order_products table:
id sub_orders_id product_id
Then on the store method:
public function store(StoreOrderRequest $request) {
$order = auth()->user()->orders()->create($request->validated());
$order_subs = $order->subOrders()->createMany($request->orders);
$order_sub_products = $request->only('subproducts');
foreach ($order_subs as $key => $value) {
$order_sub->subOrderProducts()->createMany($order_sub_products[$key]['products']);
}
}
What I wanted to achieve is to update or create those sub orders and sub order products. If the sub order is already existing, then update, otherwise create a new record with those corresponding sub order products.
Here's what I've tried so far:
public function store(UpdateOrderRequest $request, Order $order) {
$order->update($request->validated());
$order_subs = $order->subOrders()->updateMany($request->orders);
$order_sub_products = $request->only('subproducts');
foreach ($order_subs as $key => $value) {
$order_sub->subOrderProducts()->updateMany($order_sub_products[$key]['products']);
}
}
It's not working as expected since the order subs is only a single record. What's the best way or the right process for updating/creating these records? Thanks.

Laravel eloquent multiple levels of relations

Alright so I am basically trying to retrieve all animal_registry codes based on a user ID.
Idea is that
1 user has many jobs.
Jobs are consisted of many "Jobs data".
Jobs data has many "Animal registry" entries.
These are my relations
Image relations link (click)
And these are my relations in Laravel
class User
{
public function jobs()
{
return $this->hasMany('App\Models\RegistryJobs', 'employee', 'id');
}
}
class RegistryJobs extends Model
{
protected $table = "registry_jobs";
protected function jobsData()
{
$this->hasManyThrough('App\Models\AnimalRegistry', 'App\Models\RegistryJobsData', 'id', 'animal_registry_id');
}
}
class RegistryJobsData extends Model
{
protected $table = "registry_jobs_data";
public function jobs()
{
$this->belongsTo('App\Models\RegistryJobs', 'id', 'registry_jobs_id');
}
public function animals()
{
$this->hasMany('App\AnimalRegistry', 'id', 'animal_registry_id');
}
}
class AnimalRegistry extends Model
{
protected $table = "animal_registry";
}
And now I am trying to query it from a controller in a way
$data = User::whereHas('jobs', function ($query) {
$query->where('id', 1);
})->get();
But I am unable to access the properties from the animal_registry.
Can you try like this :
public function animals(){
return $this->hasManyThrough('App\Registry_Jobs_data','App\Registry_Jobs', 'employee',
'registry_jobs_id', 'id' ,'id')->join('//Do the joining')->select();
}
Check the hasManyThrough i am not sure..

How to get model relations in Laravel?

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.

Laravel Complex Relationships Through Polymorphism

I have the following models using Laravel 5.3:
Provider:
// Provider model
$primaryKey = 'id'
public function activities()
{
return $this->hasMany(Activity::class);
}
Activity:
// Activity model
$primaryKey = 'id'
public function provider()
{
return $this-belongsTo(Provider::class);
}
public function semesters()
{
return $this->hasMany(Semester::class);
}
public function semesterPurchases()
{
return $this->hasManyThrough(Purchase::class, Semester::class, 'activity_id', 'purchasable_id')
->where('purchasable_type', Semester::class);
}
Semester:
// Semester model
$primaryKey = 'id'
public function activity()
{
return $this->belongsTo(\App\Models\Activity::class, 'activity_id', 'id');
}
Purchase:
// Purchase model
$primaryKey = 'id'
public function purchasable()
{
return $this->morphTo();
}
In my case Semester::class is the purchasable_type. Is there a way to establish a relationship between Provider::class and Purchase::class? In order to make it possible to do something like this:
$providers = Provider::select('id', 'name', 'address')
->with('purchases')
->where('providers.id', 1)
->get();
I would prefer not to go through activities like so:
$providers = Provider::select('id', 'name', 'address')
->with('activities.purchases')
->where('providers.id', 1)
->get();
which I know I can do using hasManyThrough on the Activity::class
Laravel has no native support for a direct relationship.
I've created a package for cases like this: https://github.com/staudenmeir/eloquent-has-many-deep
class Provider extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function purchases()
{
return $this->hasManyDeep(
Purchase::class,
[Activity::class, Semester::class],
[null, null, ['purchasable_type', 'purchasable_id']]
);
}
}
Provider::find($id)->purchases;

How I can get the tuples in tables N to N in laravel?

I have the following data model
A technician can have many services and a service can have many technical
Tecnico Model
class Tecnico extends Eloquent{
protected $table = 'Tecnico';
protected $fillable = array('Auth_Token');
public function servicios(){
return $this->belongsToMany('Servicio', 'Servicio_Tecnico', 'idTecnico', 'idServicio');
}
}
Servicio Model
class Servicio extends Eloquent{
protected $table = 'Servicio';
public function detalleServicio(){
return $this->hasOne('Detalle_Servicio', 'idDetalle_Servicio');
}
public function tecnicos(){
return $this->belongsToMany('Tecnico', 'Servicio_Tecnico', 'idServicio', 'idTecnico');
}
}
I'm trying to get all the services of a particular technician according to the "auth_token"
ServicioController
class ServicioController extends BaseController{
public function obtenerServicios($auth){
if($auth != ''){
$tecnico = DB::table('Tecnico')->where('Auth_Token',$auth)->first();
if($tecnico != null){
$servicio = $tecnico->servicios;
$response = Response::json($tecnico);
return $response;
}else{
$array = array('Error' => 'NotAuthorizedError', 'Code' => '403');
$response = Response::json($array);
return $response;
}
}else{
$array = array('Error' => 'InvalidArgumentError', 'Code' => '403');
$response = Response::json($array);
return $response;
}
}
}
Route
Route::get('servicio/{auth}', array('uses' => 'ServicioController#obtenerServicios'));
Error
How I can get all that technical services?
First: it's best to use the Eloquent model to query instead of DB::table.
Eg:
$tecnico = Tecnico::with('servicio')->where('Auth_Token',$auth)->firstOrFail();
The DB query builder doesn't know the Eloquent relationships. Eloquent only knows the Query builder.
And second: don't pass access tokens in the URI. Not in a segment and not in the query string. Use headers for that.
Eg:
Route::get('servicio', 'ServicioController#obtenerServicios');
class ServicioController extends BaseController {
public function obtenerServicios() {
// strip the "Bearer " part.
$token = substr(Request::header('Authorization'), 0, 7);
// ...
}
}
Use Eloquent to get Eloquent results like Model::find() etc. (DB::table... will return stdObject, that's the error you get), and correct these relations:
// class Tecnico
public function servicios(){
// the keys are wrong:
// return $this->belongsToMany('Servicio', 'Servicio_Tecnico', 'idTecnico', 'idServicio');
// it should be like this:
return $this->belongsToMany('Servicio', 'Servicio_Tecnico', 'Tecnico_idTecnico', 'Servicio_idServicio');
}
// class Servicio
public function tecnicos(){
return $this->belongsToMany('Tecnico', 'Servicio_Tecnico', 'Servicio_idServicio', 'Tecnico_idTecnico');
}

Resources