My recursive function in laravel does not call itself - laravel

I am writing a recursive function to call the child record from the parent record. It seems not to be working. i am getting this error; "Trying to get property 'refid' of non-object". Where am i getting it wrong. Please any idea? below is the code Snippet.
the function controller
public function DisplayDetail($id)
{
$displayDetail = DB::table('tblmembers')
->where('refid',$id)
->get();
return $this->DisplayDetail($displayDetail->refid);
}
main controller where the function is called
public function dashboard()
{
$profile = DB::table('tblmembers')->where('username',$userid)->first();
$data['userdetail'] = $this->DisplayDetail($profile->memid);
return view('main.userArea',$data);
}
the blade where the record fetched is displayed
#foreach($userdetail as $userd)
{{ $userd->memid }}
#endforeach
my sample data
refid | memid
-------------------
12345 | 123456
123456 | 1234567
123456 | 1234568
123456 | 1234569
1234567 | 1234570
from the above table; refid: 123456 brought memid: 1234567,1234568,1234569. then refid: 1234567 brought memid: 12345670
i want to display all the memid after login in as a user with memid 123456

You are doing one thing wrong in your function DisplayDetail. Here the the correction in your function
If you want to get single item then here is the correct code.
public function displayDetail($id)
{
$displayDetail = DB::table('tblmembers')
->where('refid',$id)
->first();
if($displayDetail) {
$displayDetail['userdetail'] = $this->displayDetail($displayDetail->refid);
}
return $displayDetail;
}
And dashboard function will be look like this
public function dashboard()
{
$profile=DB::table('tblmembers')->where('username',$userid)->first();
$userDetail = $this->DisplayDetail($profile->memid);
return view('main.userArea',[
'userdetail' => $userDetail
]);
}
This is the correct code. Try this and let me know if you have another query on this.

The error:
Trying to get property 'refid' of non-object
is occuring because your database query is using ->get(), which returns a Collection, rather than an object. You cannot get the property ->refid on a Collection, you can only get it from an object that resides in the collection.
As Lakhwinder Singh shows in his code, you need to use ->first(), as this will return one object. I would suggest using ->firstOrFail(), that way you will either get back an object which matches your ID, or it will fail if it cannot find it.
If you do:
$displayDetail = DB::table('tblmembers')
->where('refid',$id)
->firstOrFail();
You will now be able to call:
$displayDetail->refid
You can use that in your function call to displayDetail.

try this function
public function DisplayDetail($id,$data=[])
{
$displayDetail = DB::table('tblmembers')
->where('refid',$id)
->get();
if($displayDetail && isset($displayDetail->refid))// your condition for last child
{
$data = $this->DisplayDetail($displayDetail->refid,$data);
}
$data[] = array('refid' =>$displayDetail->id ,
'memid' => $displayDetail->secondid );
return $data;
}
i'll explain you later first modify according to your requirement and run

Related

Get Id Field From Eloquent Laravel

I want get id value from eloquent laravel and passing to variable to insert process. this is my eloquent to get data from siswa table
$siswa = Siswa::where('nis', $row['nis'])->first();
but when accessing id value like $siswa->id I'm getting error
enter image description here
Use this code
if($siswa){
$id=$siswa->id;
}
$siswa variable can be null. Look at its contents with the dd($siswa) command.
To escape the error you can use it like this:
if($siswa)
{
// $siswa not null.
}
You have two ways to fix this.
1/ You can use ->firstOrFail() to display a 404 page in case of your data is not found :
$siswa = Siswa::where('nis', $row['nis'])->firstOrFail();
// if $siswa is NULL, then it will display a 404 page, else it will continue
2/ You can add a simple condition to continue with your data :
$siswa = Siswa::where('nis', $row['nis'])->first();
if ($siswa) {
// then continue
}
First you can $id pass on your public function like
public function show($id)
{
$siswa = Siswa::where('id', $id)->first();
}
You can pass your id on your route

Modify Laravel request before insert

Is is possible to modify a request before it gets inserted into the database?
public function store(StoreRequest $request)
{
$request->date_posted = strtotime($request->date_posted);
//insert data here.
}
Yes it can be, what you have works perfectly fine
public function store(StoreRequest $request)
{
$request->date_posted = strtotime($request->date_posted);
or
$datePosted = $request->date_posted + 2;
$datePosted = $request->date_posted . 'some other addons';
//insert data here.
}
these are just examples but i hope you get what im saying.
Fyi if you input into the db, the created_at and updated_at will update and so you don't need to insert the time the post was made manually.
Try this solution maybe can resolve your issue . Add setter in model so it will be look like this
Class ModelX {
public function setDateDatePosted Attribute($date_posted)
{
$this->attributes['date_posted'] = strtotime($date_posted);
}
}
hope it useful for you .

Laravel count column of related model

I want to count the number of upvotes and downvotes from ScripRating for a certain Script.
Script.php:
public function ratings()
{
return $this->hasMany('ScriptRating');
}
ScriptRating.php:
public function script()
{
return $this->belongsTo('Script');
}
The script_rating database table:
id (primary, increments)
script_id(integer)
rating(integer) <-- Can be either 1 (upvote) or -1 (downvote)
To retrieve a script and display the ratings:
$script = Script::where('title', '=', $title)->get();
{{ $script->ratings }}
This works fine, it returns an array: [{"id":1,"script_id":1,"rating":1}]. But at this point I'm stuck. How could I count the total upvotes and downvotes for a certain script?
I also have one more small question what I'm finding confusing. This does the same as the code above:
$script = Script::where('title', '=', $title)->with('ratings')->get();
{{ $script->ratings }}
What is the difference between these two methods and which one should I use?
Thanks in advance!
Edit
I made three scopes:
public function scopeTotalRating($query, $scriptId) {
return $query->where('script_id', $scriptId)->get()->sum('rating');
}
public function scopeThumbsUp($query, $scriptId) {
return $query->where('script_id', $scriptId)->having('rating', '=', 1)->get()->sum('rating');
}
public function scopeThumbsDown($query, $scriptId) {
return $query->where('script_id', $scriptId)->having('rating', '=', -1)->get()->sum('rating');
}
And display them as following:
{{ ScriptRating::thumbsUp($script->id) }}
You can use
{{ $script->ratings->count() }}
This will display the number total ratings a script has.
However what you're interested in doing is grouping the ratings into upvotes and downvotes, so you'll need to query your relationship by a group by clause.
Script::where('title', '=', $title)->with([
'ratings' => function($query) {
$query->groupBy('rating');
})
])->get();
I believe the collection returned should be now grouped by 1 and -1. Let me know of the results!
EDIT: You can also take a look here at the documentation on querying relationships:
http://laravel.com/docs/4.2/eloquent#querying-relations
EDIT for response:
The simplest way to do this without using group by would be separate queries:
$script = Script::where('title', $title)->first();
if ($script) {
$upvotes = ScriptRating::where('script_id', $script->id)->having('rating', '>', 0)->get()->count();
$downvotes = ScriptRating::where('script_id', $script->id)->having('rating', '<', 0)->get()->count();
}
Also the difference between your scripts mentioned is called eager loading or lazy loading. When you specify ->with() in your query, this is called eager loading. If you don't do this, the query will be ran when you specify $script->ratings
More about eager/lazy loading here:
http://laravel.com/docs/4.2/eloquent#eager-loading
Edit for another response:
You would use the ->whereHas('ratings') function if you want to gather scripts that only have ratings. You can also check the existence of the script having ratings by doing an if statement:
if ($script->ratings->count() > 0) {
// The script has ratings
} else {
// The script does not have ratings
}
If you don't want to keep repeating this code you could always put a function inside your Script.php model by using the following:
public function hasRatings()
{
return $this->ratings->count() > 0;
}
Then you can do:
if ($script->hasRatings())
You can add to the Script model class those 2 functions:
public function ratingsSumRelation()
{
return $this->hasOne('ScriptRating')->selectRaw('script_id, sum(rating) as sum_all')
->groupBy('script_id');
}
public function getRatingSumAttribute()
{
return $this->ratingsSumRelation ?
$this->ratingsSumRelation->sum_all: 0;
}
and now display sum using:
{{ $script->rating_sum }}

Error using save( ) in Laravel command

I am setting up my first Laravel command, but having an issue saving the the record.
My model:
Public static function contractorDecline(){
return DB::table('job_interviews')
->where('job_interviews.status', '=', 'awaiting contractor response')
->get();
}
I set up a command to change the status after 24 hours with no action:
public function fire()
{
//
$tooLate = Carbon::Now()->subHours(24);
$interviews = JobInterview::contractorDecline();
//
foreach($interviews as $interview){
if ($interview->response_received_on <= $tooLate){
$interview->status = 'contractor declined interview';
$interview->save();
}
}
return('finished');
}
When I run the command, I am getting the error:
"Call to undefined method stdClass::save()"
What do I need to add to the controller to be able to use save() in the command?
You are using Fluent which returns a simple object and calling Eloquent save method on it. If you want to update the row you should use Eloquent instead. Assuming you have a JobInterview class(Model) for the job_interviews table, you can code:
JobInterview::whereStatus('awaiting contractor response')->get();

getting the value of the single field output using the codeigniter active record

the following function is supposed to read the name of the given asset code from the database. but it triggers the error: "Trying to get property of non-object"
function sban_name($asset){
$this->db->select('name');
$this->db->from('asset_types');
$this->db->where('code',$asset);
return $this->db->get()->result()->row('name');
}
All I want is to have the name of the asset returned back to the controller! Your help is highly appreciated!
Use row() like,
return $this->db->get()->row()->name;
Use row() for a single row, and result() for multiple rows.
do like this, asset_types is your table name
function sban_name($asset){
$this->db->select('name');
$this->db->from('asset_types');
$this->db->where('code',$asset);
return $this->db->get('asset_types');
}
And in your controller acess it like
$result=$this->modelname->sban_name('$asset')->row();
$name=$result->name;
I think it's important to check if the record that satisfies the conditions even exists in the database. Code for the model:
function sban_name($asset){
$this->db->select('name');
$this->db->from('asset_types');
$this->db->where('code',$asset);
$row = $this->db->get()->row();
if (isset($row)) {
return $row->name;
} else {
return false;
}
}
Simply call the function from the controller like so:
$response = $this->model_name->sban_name($asset)
Try this code of block , I already checked and works fine:
function sban_name($asset)
{
$this->db->select('name');
$this->db->from('asset_types');
$this->db->where('code', $asset);
return $this->db->get()->row()->name;
}

Resources