Laravel UUID from SQL Server Database Errors - sql-server

I am having issues with a Laravel application using an existing database where MS SQL UUIDs are used. My application has a customer:
class Customer extends Model
{
protected $table = 'ERP.Customer';
public $timestamps = false;
protected $primaryKey = 'CustID';
protected $keyType = 'string';
protected $fillable = [
'CustID',
'SysRowID',
'CustNum',
'LegalName',
'ValidPayer',
'TerritoryID',
'Address1',
'Address2',
'Address3',
'City',
'State',
'Zip',
'Country',
'SalesRepCode',
'CurrencyCode',
'TermsCode',
'CreditHold',
'FaxNum',
'PhoneNum',
'CustomerType'
];
public function SalesTer()
{
return $this->belongsTo(SalesTer::class,'TerritoryID', 'TerritoryID');
}
public function Shipments()
{
return $this->hasMany(Shipment::class, 'CustNum', 'CustNum');
}
public function Equipments()
{
return $this->hasMany(Equipment::class,'CustNum', 'CustNum');
}
public function Customer_UD()
{
return $this->hasOne(Customer_UD::class,'ForeignSysRowID', 'SysRowID');
}
}
Which (in the native ERP application) has a UD table which end users can used to customise the Customer entity:
class Customer_UD extends Model
{
protected $table = 'ERP.Customer_UD';
protected $primaryKey = 'ForeignSysRowID';
public $timestamps = false;
public $incrementing = false;
protected $keyType = 'string';
protected $fillable = [
'ForeignSysRowID',
'MakesCans_c',
'MakesEnds_c',
'Industry_c'
];
public function Customer()
{
return $this->hasOne(Customer::class,'SysRowID', 'ForeignSysRowID');
}
}
CustomerController:
public function show($CustID)
{
if(Customer::find($CustID))
{
$Customer = Customer::find($CustID);
$Customer_UD = $Customer->Customer_UD()
->get();
$Shipments = $Customer->Shipments()
->where('Voided', '0')
->get();
$Equipments = $Customer->Equipments()
->with('Part') // load the Part too in a single query
->where('SNStatus', 'SHIPPED')
->get();
return view('Customer.show', ['NoCust' => '0'],
compact('Equipments', 'Customer','Shipments', 'Parts', 'Customer_UD'));
}
else
{
return view('Customer.show', ['NoCust' => '1']);
}
}
The Customer has (for whatever reason) a CustID (which people use to refer to the customer) a CustNum (which is not used outside of the database and a SysRowID. The SysRowID is used to link the Customer table with the Customer_UD table.
An example row from Customer_UD is:
My issue is that when trying to return the UD fields along with the Customer fields I get an error:
SQLSTATE[HY000]: General error: 20018 Incorrect syntax near ''.
[20018] (severity 15) [select * from [ERP].[Customer_UD] where [ERP].
[Customer_UD].[ForeignSysRowID] = '���_�X�O�Q׊3�^w' and [ERP].
[Customer_UD].[ForeignSysRowID] is not null]
I thought it was odd, so I commended out the Customer_UD lines in the CustomerController and simply tried to display the Customer UUID field in the show blade:
SysRowID: {{$Customer->SysRowID}}
I get nothing, no errors but no data. I created a controller and index blade for the Customer_UD model and can display all of the Customer_UD database fields apart from the UUID field.
I don't actually want to display the UUID fields - but do need to use them to build the relationships. Can anyone help point me in the right direction?

I found that adding:
'options' => [
PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER => true,
],
To the database configuration in config\database.php resolved the issue.

Related

Delete on cascade in Model Laravel with eloquent

I want to delete data through the api but it is showing an error because it is necessary to delete records in the properties table.
SQLSTATE[23000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server] The DELETE statement conflicted with the REFERENCE constraint "FK_Interests_Properties_User". The conflict occurred in database "CADASTRO", table "dbo.Interests_Properties", column 'interests_user_id'. (SQL: delete from [Interests_User] where [user_id] = 1515626)
I created the model that performs actions on the Interests_Properts table, but when I try to delete the data that has the same interests_user_id, errors are occurring.
InterestsUser.php:
use App\Source\InterestsProperties;
class InterestsUser extends Model
{
protected $connection = 'sql_cadastro';
protected $table = 'Interests_User';
protected $primaryKey = 'id';
public $timestamps = false;
public function properties()
{
$this->belongsToMany(InterestsProperties::class, 'foreign_key');
}
public static function lgpdInterestsUser($id_user, $action)
{
if ($action == 'search') {
$data = InterestsUser::where('user_id', $id_user)->get();
if (count($data) > 0) {
return $data;
} else {
return false;
}
} elseif ($action == 'delete') {
$data = InterestsUser::with('properties')->where('user_id', $id_user)->get();
foreach ($data->properties as $p) $p->delete();
if ($data > 0) {
return 'Success Remove.';
} else {
return 'Not Found.';
}
} else {
return "Action Incorrect!";
}
}
}
InterestsProperties.php
class InterestsProperties extends Model
{
protected $table = 'Interests_Properties';
protected $primaryKey = 'id';
public $timestamps = false;
}
The error is occurring when trying to remove with cascade:
Call to undefined method Illuminate\Database\Eloquent\Builder::foreign()
Table Structure
Interests_User
id
interest_id
user_id
created_at
updated_at
Interests_Properties
id
interests_user_id
key
value
created_at
updated_at
At DB level, using onDelete: when migrating your InterestsProperties model you'll have a line like
$table->foreignId('foreign_key')
to that add ->onDelete('cascade')
after that update each time you delete a record from the main table it will do it in this one to.
At PHP level,
$data = InterestsUser::with('properties')->where('user_id', $id_user)->first();
foreach($data->properties as $p) $p->delete();
PD: Those will remove the property record too.

Jessneggers / Laravel MongoDB whereRaw lookup not working

I migrated my database from Sql Server to MongoDB
I want to Join existing customer Table with contact Table .
Customer have multiple contacts . I tried whereRaw lookup
customer collection
{
"_id": 77,
"custid": 93
}
Contact Collection
{"_id":77,"contactid":77,"custid":93,"firstname":"Christy ","lastname":"Lambright" }
{"_id":79,"contactid":79, "custid":93,"firstname":"Marlys ","lastname":"Barry" }
Customer Modal
class custt extends Model
{
use Notifiable;
protected $primaryKey = 'id';
}
Contact Modal
class contact extends Model
{
use Notifiable;
protected $primaryKey = 'id';
In Controller
$cnt = DB::collection("custts")->raw(function($collection)
{
$more_where = [];
$more_where[]['$lookup'] = array(
'from' => 'contacts',
'localField' => 'custid',
'foreignField' => 'custid',
'as' => 'country',
);
return $collection->aggregate($more_where);
});
Error comes --
Empty Results
I tried Lots of options for hasMany and belongstoMany . Not working ...
please suggest
ok , finally found it working
source - https://github.com/jenssegers/laravel-mongodb/issues/841
$cnt = custt::raw(function($collection)
{
return $collection->aggregate(
[[
'$lookup' => [
'as'=>'info',
'from'=>'contacts',
'foreignField'=>'custid',
'localField'=>'custid'
]
]]
);
});

How to insert into a table based on an Eloquent relationship an array of foreign keys

I have two models TeamMember and ProjectRequest.
A TeamMember can have one ProjectRequest, that is why I created the following Eloquent relationship on TeamMember:
class TeamMember extends Model {
//
protected $table = 'team_members';
protected $fillable = ['project_request_id'];
// Relations
public function projectTeam() {
return $this->hasOne('\App\Models\ProjectRequest', 'project_request_id');
}
}
In my Controller I want to query both tables, however it returns the failure message.
What is important to know is that $request->projectTeam is an array of emails, looking like this:
array:2 [
0 => "mv#something.com"
1 => "as#something.com"
]
Meaning that I need to bulk insert into team_members table the project_request_ id for each team member where the emails are in the array.
How can I do that in the right way? The following is my attempt:
public function createProjectTeam(Request $request){
try {
$title = $request->projectTitle;
$TeamMember = $request->projectTeam;
$projectRequest = ProjectRequest::create(['project_title' => $title]);
$projectRequestId = $projectRequest->id;
$projectTeam = $this->teamMembers->projectTeam()->create(['project_request_id'=> $projectRequestId])->where('email', $TeamMember);
//$projectTeam = TeamMember::createMany(['project_request_id' => $projectRequestId])->where($TeamMember);
//dd($projectTeam);
return $projectRequest.$projectTeam;
} catch(\Exception $e){
return ['success' => false, 'message' => 'project team creation failed'];
}
}
There are a few things you can do.
Eloquent offers a whereIn() method which allows you to query where a field equals one or more in a specified array.
Secondly, you can use the update() method to update all qualifying team members with the project_request_id:
public function createProjectTeam(Request $request)
{
try {
$projectRequest = ProjectRequest::create(['project_title' => $request->projectTitle]);
TeamMember::whereIn('email', $request->projectTeam)
->update([
'project_request_id' => $projectRequest->id
]);
return [
'success' => true,
'team_members' => $request->projectTeam
];
} catch(\Exception $e) {
return [
'success' => false,
'message' => 'project team creation failed'
];
}
}
I hope this helps.

How to convert MySQL query to Eloquent Relationships?

I don't really know what words or terms I would search. I have also read the documentation in laravel 5.7, https://laravel.com/docs/5.7/eloquent-relationships#many-to-many-polymorphic-relations.
But still I couldn't find the thing that I want.
The result that I am expecting is this in MySQL:
SELECT id as product_id, (SELECT name FROM products WHERE id = transactions.product_id), created_at FROM transactions WHERE user_id = 1
This is the result of the mysql query:
I already have a model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Transactions extends Model
{
protected $table = 'transactions';
protected $fillable = [
'user_id', 'product_id'
];
public function product()
{
return $this->hasOne('App\Products')->select('name');
}
}
?>
Then in my controller:
public function transactions()
{
$transactions = new Transactions::where('user_id',Auth::id())->product;
return view('transactions', ['transactions' => $transactions]);
}
You should use belongsTo() relation. Transaction belongs to one product, product has many transactions.
Also, you can (or better should) rename model to a singlular. Then you don't need to use protected $table.
It is not necessarily to select only name.
Transaction model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Transaction extends Model
{
protected $fillable = ['user_id', 'product_id'];
public function product()
{
return $this->belongsTo('App\Product');
}
}
Controller:
public function transactions()
{
$transactions = Transaction::with('product')
->where('user_id', Auth::id())
->get();
return view('transactions', ['transactions' => $transactions]);
}
View:
#foreach($transactions as $transaction)
echo $transaction->product_id; //attribute product_id of transaction
echo $transaction->product->id; //attribute id of product
echo $transaction->product->name; //attribute name of product
#endforeach

Symfony3 FOS UserBundle how to load choice as entity

I am using Symfony3.1 with FOS UsersBundle and I want some added fields to be loaded as specific Entity.
In RegistrationType I have
->add('country', ChoiceType::class, array(
'label' => 'label.country',
'required' => false,
'placeholder' => 'label.select_country',
'choices' => array(
'France' => '7v8tqr',
),
))
In my Entity User I have
/**
* #ORM\OneToOne(targetEntity="Country")
* #ORM\JoinColumn(name="country", referencedColumnName="short")
*/
protected $country;
I can't use the EntityType as it loads every available entity and I use the same kind of field for provinces and cities which are quite huge (I manage their content with javascript).
When I load a registered user, the country field is served as a Country Entity but when I register a new user or modify an existing one, I only have the string "short" which causes an error Expected value of type "AppBundle\Entity\Country" for association field "AppBundle\Entity\User#$country", got "string" instead..
Is there a solution ?
Thanks to #mcriecken who led me in the right direction, I have implemented the following solution, using an EventListener
in services.yml
app_user.registration:
class: AppBundle\EventListener\UserRegistrationListener
arguments: ['#doctrine.orm.entity_manager']
tags:
- { name: kernel.event_subscriber }
and the EventListener UserRegistrationListener.php
<?php
namespace AppBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Doctrine\ORM\EntityManager;
class UserRegistrationListener implements EventSubscriberInterface
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* {#inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
);
}
public function onRegistrationSuccess(FormEvent $event)
{
$form = $event->getForm()->getData();
//Gets the locations
$form->setCountry($this->getCountry($form->getCountry()));
$form->setProvince($this->getProvince($form->getProvince()));
$form->setCity($this->getCity($form->getCity()));
}
//Loads the country as an entity
public function getCountry($short)
{
if ($short == null) return null;
$repository = $this->em->getRepository('AppBundle:Country');
return $repository->findOneByShort($short);
}
//Loads the province as an entity
public function getProvince($short)
{
if ($short == null) return null;
$repository = $this->em->getRepository('AppBundle:Province');
return $repository->findOneByShort($short);
}
//Loads the city as an entity
public function getCity($short)
{
if ($short == null) return null;
$repository = $this->em->getRepository('AppBundle:City');
return $repository->findOneByShort($short);
}
}
Then at the end my FOS User object contains COuntry, Province and City as Objects and it can be saved to DB :-)

Resources