I don't know how to get just one record from the database. I'm doing it with foreach, as if it were several records. How can i get just one record?
this is my code:
$usuario = \DB::select('SELECT * FROM usuarios where id=:id',['id' => session('id')]);
foreach ($usuario as $u)
{
$nombre=$u->nombre;
$email=$u->email;
}
As pointed out by #lagbox, you are using the select function which will return an array.
So in order to get the first element, you would do:
$usuarios = \DB::select('SELECT * FROM usuarios where id=:id',['id' => session('id')])->get();
if(!empty($usuarios)) {
$usuario = $usuarios[0];
}
But you'd probably be better using the query builder, like this:
$usuario = \DB::table('usuarios')->where('id', session('id'))->first();
// $nombre = $usuario->nombre;
// $email = $usuario->email;
Related
Trying to save data while open page but stuck at error :
"Method Illuminate\Database\Eloquent\Collection::save does not exist."
I have 2 database :
Buffalodata
Buffalomilkrecord
From 2nd table i need to get the avg of totalmilk and update the same to main database (1). This help me to show updated avgmilk data on dashboard front page.
Route:
Route:: get('buffalo-details', 'App\Http\Controllers\BuffalodataController#buffalodetails');
BuffalodataController Controller :
public function buffalodetails()
{
$buffalidforavgmilk = Buffalodata::groupBy('buffaloID')->get('buffaloID')->pluck('buffaloID')->toArray();
foreach ($buffalidforavgmilk as $id )
{
$milkperid = Buffalomilkrecord::where('buffaloID', $id)->sum('totalmilk');
$avgbuffalocount = Buffalomilkrecord::where('buffaloID',$id)->count();
$getavg = $milkperid / $avgbuffalocount;
$data = Buffalodata::find($buffalidforavgmilk);
$data->avgmilk = ($getavg);
$data->save ();
// dump([$milkperid,$avgbuffalocount,$getavg,$data,$id]);
}
return view ('pages.Buffalo.BuffaloDetails',[---------]);
}
Thanks again in Advance
When you pass an Array to ::find(), it returns a Collection, which doesn't have a save() method. This is your code:
// This is an Array of `buffaloID` values
$buffalidforavgmilk = Buffalodata::groupBy('buffaloID')->get('buffaloID')->pluck('buffaloID')->toArray();
...
// `$data` is now a `Collection` of `Buffalodata` instances
$data = Buffalodata::find($buffalidforavgmilk);
// This now fails, as `Collection` doesn't have a `save()` method
$data->save();
You can rewrite your code as follows:
Buffalodata::whereIn('buffaloID', $buffalidforavgmilk)->update(['avgmilk' => $getavg]);
This will update all records in a single call. If you want to iterate, that's an option too:
$data = Buffalodata::find($buffalidforavgmilk);
foreach ($data as $record) {
$record->avgmilk = $getavg;
$record->save();
}
Or, since you have $id already:
$record = Buffalodata::find($id);
$record->avgmilk = $getavg;
$record->save();
Problem Description
I want to cache the query results with the key as a whole SQL statement instead part of the SQL statement like the below example:
// Generate a key based on a simple checksum
// of the query's where clause
$query->cache(function ($q) {
return md5(serialize($q->clause('where')));
});
Above example taken from this link : https://book.cakephp.org/4/en/orm/query-builder.html#caching-loaded-results
What I have tried
I can get the full SQL without the binding value like this:
$query->sql()
And the binding values like this:
$bindings = $query->getValueBinder()->bindings();
Now I need to figure out how to combine the both. It would be best if there is a built in function in CakePHP which would just give me the SQL with the binding value.
I have found the solution to this. There is a private function in DebugKit named interpolate() which create the full SQL statement with the binding value.
As the function is private, you have to copy it and save it in your source code.
Here's the interpolate function :
/**
* Helper function used to replace query placeholders by the real
* params used to execute the query.
*
* #param string $sql The SQL statement
* #param array $bindings The Query bindings
* #return string
*/
private static function interpolate($sql, array $bindings)
{
$params = array_map(function ($binding) {
$p = $binding['value'];
if ($p === null) {
return 'NULL';
}
if (is_bool($p)) {
return $p ? '1' : '0';
}
if (is_string($p)) {
$replacements = [
'$' => '\\$',
'\\' => '\\\\\\\\',
"'" => "''",
];
$p = strtr($p, $replacements);
return "'$p'";
}
return $p;
}, $bindings);
$keys = [];
$limit = is_int(key($params)) ? 1 : -1;
foreach ($params as $key => $param) {
$keys[] = is_string($key) ? "/$key\b/" : '/[?]/';
}
return preg_replace($keys, $params, $sql, $limit);
}
}
And then call it and pass the SQL and the binding values like this to get the whole SQL statement with the binding values:
$sql = $query->sql();
$bindings = $query->getValueBinder()->bindings();
// to make the example easier, I have saved the interpolate function in controller
$properSqlStatement = $this->interpolate($sql, $bindings);
🎉 Yay !
I'm sending a series of loops from controller to viewe but I have to return a loop in it.
i want to do something like code
$sor1 = mysql_query("select * from dersler");
while(mysql_fetch_object($sor1)) {
$dersid = $sor1->id;
$sor = mysql_query("select * from gecilendersler where dersid='$dersid'");
while(mysql_fetch_object($sor)) {
echo $sor->dersadi;
}
}
$uyeid =Auth::user()->id;
$dersler = DB::table('dersler')->where('uyeid', $uyeid)->get();
foreach($dersler as $ders) {
$dersid=$ders->id;
}
$saatler = DB::table('saatler')->where('dersid', $dersid)->get();
return view('sayfalar.saatler')
->with([
'dersler' => $dersler,
'saatler' => $saatler
]);
Â
I did it this way, but the last record remains in the last line in other records
I want to store a list of departments in my database. I do not create the departments in my system, I obtain them from Active Directory. In the view for departments, I display all the departments. I also have a button to update departments in the database.
This function at the moment looks like the following
public function updateDepartments()
{
$departments = Helper::returnDepartmentsFromLdap();
dd($departments);
}
The dd produces something like the following
array:16 [â–¼
0 => "Department 1"
8 => "Department 2"
21 => "Department 3"
22 => "Department 4"
29 => "Department 5"
43 => "Department 6"
47 => "Department 7"
48 => "Department 8"
]
You have to remember though that this list is not being obtained from my database, it is being obtained from Active Directory. However, I now want to add them to my database. So in the same function I do the following
public function updateDepartments()
{
$departments = Helper::returnDepartmentsFromLdap();
foreach($departments as $departmentID => $departmentName) {
$department = new Department();
$department->departmentID = $departmentID;
$department->departmentName = $departmentName;
$department->save();
}
return Redirect::route('departments.index')->with('message', 'Departments updated.');
}
Now the problem with the above is that every time the button is pushed, the database will insert new rows. Say I push the button for the first time, my database will be populated with the list. Say I then push it a second time, I do not want the same list added again. If it already exist in the database, it should overwrite it or something. It should only perform a save if a new item is in the list.
Is something like this possible?
Thanks
Try this approach:
public function updateDepartments()
{
$departments = Helper::returnDepartmentsFromLdap();
foreach($departments as $departmentID => $departmentName) {
$department = Department::firstOrCreate(['departmentID' => $departmentID, 'departmentName' => $departmentName]);
}
return Redirect::route('departments.index')->with('message', 'Departments updated.');
}
This is basic idea. Now if this is not clear give me info what you want to update and I will change this impl according to your requirements. For example you could do this:
public function updateDepartments()
{
$departments = Helper::returnDepartmentsFromLdap();
foreach($departments as $departmentID => $departmentName) {
$department = Department::firstOrNew(['departmentID' => $departmentID]);
$department->departmentName = $departmentName;
$department->save();
}
return Redirect::route('departments.index')->with('message', 'Departments updated.');
}
This is according to eloquent documentation
Other Creation Methods
There are two other methods you may use to create models by mass assigning attributes: firstOrCreate and firstOrNew.
The firstOrCreate method will attempt to locate a database record using the given column / value pairs. If the model can not be found in the database, a record will be inserted with the given attributes.
The firstOrNew method, like firstOrCreate will attempt to locate a record in the database matching the given attributes. However, if a model is not found, a new model instance will be returned. Note that the model returned by firstOrNew has not yet been persisted to the database. You will need to call save manually to persist it:
// Retrieve the flight by the attributes, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// Retrieve the flight by the attributes, or instantiate a new instance...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
public function updateDepartments()
{
$departments = Helper::returnDepartmentsFromLdap();
$savedDepartments = Department::select('departmentID')->get();
foreach ($departments as $departmentID => $departmentName) {
$alreadySaved = false;
foreach ($savedDepartments as $item) {
if ($item->departmentID == $departmentID) {
$alreadySaved = true;
break;
}
}
if (!$alreadySaved) {
$department = new Department();
$department->departmentID = $departmentID;
$department->departmentName = $departmentName;
$department->save();
}
}
return Redirect::route('departments.index')->with('message', 'Departments updated.');
}
Little more complex but should be faster
I have a user entity and I'm trying to update it from a UserService. The problem comes when I try to update a property which is set as an array collection.
/**
*
* #param \Doctring\Common\Collections\Collection $property
* #OneToMany(targetEntity="Countries",mappedBy="user", cascade={"persist", "remove"})
*/
private $countries;
I'm not sure if I'm supposed to somehow delete all the $countries before I set them back or if there's a way to select which ones to delete and set up the different ones....this is what my updateUser method looks so far:
public function updateUser($user) {
$entity = $this->getUser($user['id']);
if (!$entity)
throw new Exception('Error saving user!');
$countries = $this->getCountriesArray($user); //countries already set in the db
$tempCountries = array();
$delete = array();
foreach ($countries as $country) {
$found = false;
if (in_array($country, $user['countries'])) {
$tempCountries[] = $country;
} else {
$delete[] = $country;
}
}
$tempCountries = array_unique(array_merge( //combine the countries from the db we want to leave
$tempCountries, //with those the user selected
$user['countries']));
...
//here I need something to remove the countries in $delete...right?
...
$entity->setEmail($user['email']);
$entity->setResponsable($user['responsable']);
$entity->setPassword($this->createPass($user['password']));
$entity->setUrl($user['url']);
$entity->setRole($user['role']);
$modelCountries = array();
foreach($tempCountries as $c) {
$p = new Countries();
$p->setCountryName($c);
$p->setUser($entity);
$modelCountries[] = $p;
}
$entity->setCountries($modelCountries);
$this->em->persist($entity);
$this->em->flush();
}
please stackOverflow... give me a hand making sense out of this.
It actually depends on your use case.
As you said, you can either delete all countries before to set the new ones, or compute the delta, and update only the needed ones.
What countries are you providing to your service? The delta? Or full list?
Do you have performance constraints? If yes, what is the cost of a DELETE statements vs SELECT then UPDATE?
Compute delta, then UPDATE can be tricky and difficult, in most case, you better want to just DELETE all and INSERT.
For my current and personal choice I am using DQL to DELETE all owing side rows for the mapped entity and then inserting the new one.
class Rule
{
/**
* #OneToMany(targetEntity="Tier", mappedBy="rule", cascade={"persist", "remove"})
* #JoinColumn(name="ruleId", referencedColumnName="ruleId")
* #var Tier[]
*/
public $tiers;
So when I am passing new Tier in my call I am simply Deleting the all Tiers for that Role from the Rule Mapper
public function resetTiers($ruleId)
{
$modelClass = "Tier";
$q = $this->doctrineEntityManager->createQuery("Delete from $modelClass m where m.rule =" . $ruleId);
$numDeleted = $q->execute();
return $numDeleted;
}
and then calling the usual
$this->doctrineEntityManager->persist($rule);
$this->doctrineEntityManager->flush();
Hope that helps