Laravel 4 hasMany with WHERE clause - laravel

Not sure if this is the correct way to add an additional query to the hasMany argument but was unsuccessful. Is this possible?
public function menuItems($parent=false){
if($parent){
$menuItems = $this->hasMany('MenuItem')->where('parent',$parent);
}else{
$menuItems = $this->hasMany('MenuItem');
}
return $menuItems;
}
When called using
$menu_items = $menu->menuItems(0);
This just seems to return an empty array when passed a parent. Even though data with MenuItem->parent = 0 exists
Do I need to some way distinguish I'm asking for my linked items "parent" and not the main models "parent"

public function menuItems(){
return $this->hasMany('MenuItem');
}
Called with
$menu_items = $menu->menuItems()->where('parent', 0)->get();

I am not sure about the query part but at first wouldn't passing a 0 to the function still register the $parent variable as false? So maybe just check if the $parent is not null.
public function menuItems($parent = null){
if(!$parent == null)){
$menuItems = $this->hasMany('MenuItem')->where('parent',$parent);
}else{
$menuItems = $this->hasMany('MenuItem');
}
return $menuItems;
}

In PHP 0 = FALSE, change this
if( $parent ){
for this
if( $parent !== false ){

Related

empty string from DB to null ??? if($var === null){ statement}

I im chechking DB if there is record. and if there is no recod i wanna make one. But i cant get NULL from DB i got empty string. how can i solve this?
public function chechk_slots(){
$character_id = Auth::user()->id;
$inv_user = DB::table("slots")->where('character_id', $character_id)->get();
return $inv_user?? null ;
}
and
public function to_inventary()
{
$a = "Is record";
$b = "there is no record";
$character_id = Auth::user()->id;
$inv_items = DB::table("items_chars")->where('character_id', $character_id)->get();
$user_profile = $this->show_profile();
$slot = $this->chechk_slots();
//dd($slot);
//DB::table("slots")->insert(['character_id' => $character_id]);
// dd($slot[0]->character_id);
if($slot === null){
dd($b);
DB::table("slots")->insert(['character_id' => $character_id]);
}
else{
dd($a);
}
//return view('inventary', compact('user_profile', 'inv_items'));
}
my table in DB pic
There is no record
if I dd($slot); i got this pic
so empty string !=null and cant get a record...How can i change this?
Issue #1 - Collection
You will get a collection even if it has no data.
$inv_user = DB::table("slots")->where('character_id', $character_id)->get();
Issue #2 - Null coalescing
It similar to the ternary operator, but will behave like isset on the lefthand operand instead of just using its boolean value.
$inv_user = DB::table("slots")->where('character_id', $character_id)->get();
return $inv_user ?? null;
$inv_user assigned Illuminate\Support\Collection.
Solution
Use count() and ternary operator.
public function chechk_slots(){
$character_id = Auth::id();
$inv_user = DB::table("slots")->where('character_id', $character_id)->count();
return $inv_user ?: null ;
}
I guess if you want to get null from the query just use first() instead of get() and return the result in one line
return DB::table("slots")->where('character_id', $character_id)->first();

How can i seed with faker a random id or null in Laravel?

I am trying to seed a parent_id column with a random id of the same table or let it be null.
This i thought it will work:
...
'parent_id' => $faker->boolean() ? Page::all()->random()->id : null,
...
But i get the following error:
You requested 1 items, but there are only 0 items available.
Does anyone know how to do this?
Update1:
Using pseudoanime answer i tried the flowing :
$factory->define(Page::class, function (Faker\Generator $faker) {
...
$parent_id = null;
...
$has_parent = $faker->boolean(50);
Log::debug('$has_parent' . $has_parent);
if ($has_parent) {
$parents = Page::all();
Log::debug('$parents' . count($parents));
if ($parents->isEmpty()) {
Log::debug('isEmpty');
$parent_id = null;
} else {
Log::debug('$parents->random()' . print_r($parents->random(), true));
$parent_id = $parents->random()->id;
}
}
return [
...
'parent_id' => $parent_id,
...
];
}
From what i can see every time it is run Page::all(); return empty.
Any idea why that is?
Try this:
'parent_id' => $faker->boolean(50) ? Page::orderByRaw('RAND()')->first()->id : null,
Essentially we're saying, order by random, get the first and then get it's id.
boolean(50) should give you a 50% chance of true, so 50% false.
$factory->define(Page::class, function (Faker\Generator $faker) {
$ids = Page::pluck('id')->toArray();
return [
'parent_id' = empty($ids) ? null : $faker->optional(0.9, null)->randomElement($ids); // 10% chance of null
];
});
Given "Parent" as the parent model, I do this:
first seed the Parent;
seed the Child table using this code in the factory:
'parent_id' => $faker->optional()->randomElement(App\Parent::all()->pluck('id'))
It works because faker's randomElement() takes an array which you populate with all and only the 'id' values of the parent table.
The optional() faker's modifier does or doesn't put a NULL in the parent_id at random. As stated in faker's GitHub, optional() sometimes bypasses the provider to return a default value instead (which defaults to NULL).
You can also specify the probability of receiving the default value and the default value to return.
NB: you can't do anything if the Parent table isn't seeded. If so, consider the answer of dlnsk.
Your error is happening because your query to page (page:all()->random()) returns no results.
Basically your issue is that you care trying to create a parent to a page before a page is even created.
You can should try something like check if the Page::all() returns a non empty collection, if yes, then get a random element from there, if not, create a new element.
I personally would do something like create a class for null parent element & one that would do null & non-empty parent element.
$factory->defineAs(Page::class, 'ParentPage', function (Faker $faker) {
return [
//the rest of your elements here
'parent_id' => null
];
});
$factory->defineAs(Page::class, 'page', function (Faker $faker) {
$has_parent = $faker->boolean();
if($has_parent) {
$parents = Page::all();
if($parents->isEmpty()) {
$parent_id = factory(Page::class, 'ParentPage')->create()->id;
} else {
$parent_id = $parents->random()->id;
}
}
return [
//the rest of your elements here
'parent_id' => $has_parent? $parent_id : null
];
});
You can create regular pages like factory(Page::class, 'page')->times(50)->create(); in your seeder
The code above is not tested, but the logic should be correct.
public function run()
{
factory(\App\Comment::class, 30)->make()->each(function ($comment){
$comments = Comment::all();
if ($comments->count() == 0) {
$comment->parent = null;
} else {
$rand = random_int(1, $comments->count());
if ($rand >= 2 && $rand <= 5){
$comment->parent = null;
}elseif ($rand >= 12 && $rand <=17){
$comment->parent = null;
}elseif ($rand >= 22 && $rand <= 27){
$comment->parent = null;
}else{
$comment->parent = $rand;
}
}
$comment->save();
});
}

Laravel hasMany when parent doesn't exist

Parent.php
class Parent extends Model
{
public function children() {
return $this->hasMany('App\Child');
}
}
and I used this in my controller:
$children = Parent::find($parent_id)->children;
and it's OK when $parent_id exist. But when $parent_id` doesn't exist. it returns this error:
Trying to get property 'children' of non-object
What is the solution to prevent this error or return a false?
Solution is simple:
<?php
$children = null;
$parent = Parent::find($parent_id);
if ($parent) {
$children = $parent->children;
}
return $children; // or return false, or throw Exception - whatever you like
The above would return a HasMany relation if the parent exists, or false if it doesn't.
If you need a collection regardless - a better way would be to do it another way round, like this:
<?php
$children = Children::where('parent_id', $parent_id)->find();
return $children;
use Illuminate\Database\Eloquent\Collection;
$parent = Parent::find($parent_id)
$chilren = is_null($parent) ? Collection::make([]) : $parent->children; This is the first solution
You check if the parent is not null then use has many relation or return empty eloquent collection
or you can get children by parent id
Child::where('parent_id', $parent_id)->get()
$childData='';
$parentdata = Appuser::find($parent_id);
if(isset($parentdata)){
$childData = $parentdata->order;
}
return $childData;

Laravel 5.4 Collection Map Return Values

I'm having trouble creating a function on collection map with return values.
public function getCollectionFakeId($collection, $fieldNames){
$optimus = $this->optimus;
$result = $collection->map(function($item, $key) use ($optimus, $fieldNames) {
return [
$fieldNames[0] =>$optimus->encode($item->id),
$fieldNames[1] => $item->lastname
];
}) ;
dd($result);
return json_decode(json_encode($result), FALSE);
}
As you can see the return fieldNames[0] is being hardcoded. I don't know how many fieldNames it will received. I need to return those fieldnames with obfuscated Id. So basically The only changed is the Id. Here is the screenshot.
As you can see the fieldNames are just 2 but what if it becomes 5 or 6. I don't really know how many fieldNames they are going to pass in the parameter. How can I return it. Thanks.
In case someone will encounter this problem. Here is my solution...
public function getCollectionFakeId($collection, $fieldNames){
$optimus = $this->optimus;
$result = $collection->map(function($item, $key) use ($optimus, $fieldNames) {
$mapFieldNames = array_map(function($v) use ($optimus, $item) {
if( $v == 'id'){
return $optimus->encode($item->id);
}
else{
return $v;
}
}, $fieldNames);
return $mapFieldNames;
}) ;
dd($result);
return json_decode(json_encode($result), FALSE);
}
The result is the same. AWESOME!

Laravel Function Not Updating Database

I am calling the function below
function makeanote($type,$id){
$note = Notification::where("user_id",Auth::user()->id)->get();
if ($type == "user"){
if($id > $note->pluck("users") ){
$note->users = $id;
$note->save();
return;
}
}
return;
}
Like so: makeanote($type,$id). The calling $type is "user" and the calling $id is "31".
In the database for my current user, the $note value at the users column is currently zero (0).
Therefore I would expect it to update to 31, but it is staying at zero. Am I using pluck() incorrectly?
Thank you.
Give this a shot:
function makeanote($type,$id){
$note = Notification::where("user_id",Auth::user()->id)->first();
if ($type == "user"){
if($id > $note->users){
$note->users = $id;
$note->save();
return;
}
}
return;
}
My changes are: ->first() (this will return a single object) instead of ->get() (this returns a object collection) and once you have the object you can access the users attribute directly.

Resources