Laravel Error: Trying to get property of non-object - laravel

I am getting an error
Trying to get property of non-object (View: C:\xampp\htdocs\laravel\proj\resources\views\mycases.blade.php)
I have defined a relationship between two models Ccase and Hiring.
public function hirings()
{
return $this -> hasMany('App\Hiring', 'case_ID')->orderBy('id','desc');
}
and paginating the results using a method below
public function getHiringsPaginateAttribute($perPage)
{
return $this->hirings()->paginate($perPage);
}
The other model 'Hiring' has a method to define relationship with Ccase as follows:
public function ccase()
{
return $this->belongsTo('App\Ccase', 'id');
}
In my controller, I have following code:
if(isset($search_term))
{
$search_term = preg_replace('/\s+/', ' ', $search_term);
$search_term = trim($search_term);
if (strlen($search_term) > 0 && strlen(trim($search_term)) == 0)
$search_term = NULL;
$search_terms = explode(' ',$search_term);
$fields = array('id', 'title', 'case');
$hirings = $hirings->whereHas('ccase', function($q) use ($search_terms, $fields){
foreach ($search_terms as $term)
{
foreach ($fields as $field)
{
$q->orWhere($field, 'LIKE', '%'. $term .'%');
}
}
});
}
$hirings = $hirings->getHiringsPaginateAttribute($results_per_page);
In mycases.blade.php, my code is
{{$hiring->ccase->id}}
This line is throwing the above said error while the output of {{$hiring->ccase}} is:
{"id":1,"case":"HI this is a sample case i am putting just for test.","created_at":"2015-02-22 11:54:09","updated_at":"2015-02-22 11:54:09"}
What might be wrong with the code?

Unfortunately, you can't use related models in views. Here's the detailed explanation why.
Your case can be solved by specifying the name of the associated column on the parent table:
return $this->belongsTo('App\Ccase', 'ccaseId', 'id');
In model Hiring, it will be like
public function ccase()
{
return $this->belongsTo('App\Ccase', 'case_ID', 'id');
}
And now in view use it like this:
{{ $hiring->ccase->id }}

Not sure, but i think that you could use relations in view, you should use an eager loading in controller where you are quering for $hirings, just add a:
with(['hirings.ccase'])
Could you please provide a peace of code from controller where you make a query to Hiring model for clear?

Related

retrieving related field in controller index function gives error but ok in show function

I define the relation in Company table (where I added the plural):
protected $table = 'companies';
public function country() {
return $this->belongsTo(Country::class, "country_id")->withDefault(['country' => 'unknown']);
}
I also did the same in the Country model.
When I use the following code in the controller show function it works:
public function show (Company $company) {
$company->country = $company->country()->pluck('country');
But if I use the same code in the index function in a loop, I get an error "Call to undefined method stdClass::country()":
public function index (Company $company) {
if (request('tag')) {
$companies = Tag::where('name',request('tag'))->firstOrFail()->companies;
$companies->page_title = "Businesses matching tag '".request('tag')."'";
} else {
$companies = DB::table('companies')
->where([['is_active', '=', '1']])
->orderBy('company')
->get();
}
foreach($companies as $key => $thisCompany) {
...
$thisCompany->country = $company->country()->pluck('country');
}
I guess it is due to the fact that $company is created in the loop and not passed through the function like in show(Company $company)... but I could not find how to solve this issue... so help will be appreciated.
I have added the model in the argument of the function and change the name of the $company variable in the loop by $thisCompany to avoid confusion with the $company model.
No error but the field $country->country does not contain the name of the country but "Illuminate\Support\Collection {#443 …1}"
Why is it so complicated? Please help...
Paul, sorry, I think I didn't explain myself well in the comments.
What I meant by "What about if you change DB::table('companies') by Company?", is to stop using DB Query Builder to use the Eloquent Company model.
Specifically in this segment of code:
$companies = DB::table('companies')
->where([['is_active', '=', '1']])
->orderBy('company')
->get();
So, it could be:
$companies = Company::where([['is_active', '=', '1']])
->orderBy('company')
->get();
The explanation is that in the first way (with DB Query Builder), the query will return a collection of generic objects (the PHP stdClass object) that do not know anything about the Company and its relationships.
On the other hand, if you use the Eloquent model Company, it will return a collection of Company objects, which do know about relationships, and specifically the relationship that you have defined as country.
Then, when you loop over the collection, you will be able to access the country relation of each Company object:
foreach($companies as $key => $company) {
//...
$company->country = $company->country()->pluck('country');
}
Finally, your code could looks like:
public function index () {
if (request('tag')) {
$companies = Tag::where('name',request('tag'))->firstOrFail()->companies;
$companies->page_title = "Businesses matching tag '".request('tag')."'";
} else {
$companies = Company::where([['is_active', '=', '1']])
->orderBy('company')
->get();
}
foreach($companies as $key => $company) {
//...
$company->country = $company->country()->pluck('country');
}
//...
}

Laravel - Return only multiple relationships with records from controller or model

I'm returing a model with all the related models.
My problem is that perhaps some models don't have records so they are returned in my $property variable as empty and I have to evaluate their existence in blade (not done yet)
Is there any way in controller or parent model to return only the child relationships which have records? Or any blade directive to evaluate these cases?
All relationships are 1:M.
Regards!
Controller Code
class PropertyController extends Controller
{
public function details($id)
{
$property = Property::with('attributes', 'addons', 'distributions', 'images', 'attributes_2', 'services')
->where('prop_id', $id)
->first();
// dd($property);
return view('pages.processes.offerdemand.matchs.propertymodal', compact('property'));
}
}
Sir u have the same result with this code?? (just trying to help, im new in this world)
return view('pages.processes.offerdemand.matchs.propertymodal', compact(array('property')));
class PropertyController extends Controller
{
public function details($id)
{
$relations = ['attributes', 'addons', 'distributions', 'images', 'attributes_2', 'services']
$property = Property::with($relations)->whereHas($relations)
->where('prop_id', $id)
->first();
// dd($property);
return view('pages.processes.offerdemand.matchs.propertymodal', compact('property'));
}
}
SOLUTION
I changed code as follows and recieved the expected result:
public function details($id)
{
$property = Property::with(['attributes' => function ($builder) {
$builder->where('pa_value', '!=', '');
}])
->with('addons', 'distributions', 'images', 'attributes_2', 'services')
->where('prop_id', $id)
->withCount('attributes', 'addons', 'distributions', 'images', 'attributes_2', 'services')
->first();
dd($property);
return view('pages.processes.offerdemand.matchs.propertymodal', compact('property'));
}

Orwhere has method does not allow null

enter image description hereI am trying to implement a many to many relationship search with 2 models.
i get input from multiple checkbox values and want to search for items that match A or B when there is an input of data.
I read this url and wrote the same logic.
https://laracasts.com/discuss/channels/laravel/many-to-many-relationship-with-2-pivot-table-data-search
public function search(Request $request)
{
$languages = $request->lang;
$fields = $request->field;
$agencies = Agency::with('languages')->with('specialized_fields')
->orWhereHas('languages', function($query) use ($languages) {
$query->whereIn('language_id', $languages);
})
->orWhereHas('specialized_fields', function($query) use ($fields) {
$query->whereIn('specialized_field_id', $fields);
})
->get();
dd($agencies);
}
i expected to achieve A or B search but instead I got this error.
Argument 1 passed to Illuminate\Database\Query\Builder::cleanBindings() must be of the type array, null given, called in /var/www/jtf/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php on line 907
it seems that it causes this error if either A or B is null, but why??? Does the OrWhereHas method work only when theres an input??
/added info/
my error message
my agency model
class Agency extends Model {
protected $guarded = [
'id'
];
public function languages(){
return $this->belongsToMany('App\Language');
}
public function specialized_fields(){
return $this->belongsToMany('App\SpecializedField');
}
public function region(){
return $this->hasOne('App\Region');
} }
I believe it's because either $languages or $fields is null.
Since ->whereIn() is expecting an array, but you're passing null.
You just need to make sure you're passing an array.
$languages = array_filter((array) $request->lang); // cast to array & remove null value
$fields = array_filter((array) $request->field);
$agencies = Agency::with('languages', 'specialized_fields')
->orWhereHas('languages', function($query) use ($languages) {
$query->whereIn('language_id', $languages);
})
->orWhereHas('specialized_fields', function($query) use ($fields) {
$query->whereIn('specialized_field_id', $fields);
})
->get();
I'm speculating that you started your where query chain with an orWhereHas() which may have caused the problem, try starting with whereHas() instead.
public function search(Request $request){
$languages = $request->lang;
$fields = $request->field;
$agencies = Agency::with('languages', 'specialized_fields') // you can get away by just using one with(), not needed but its cleaner this way
->whereHas('languages', function($query) use ($languages) { // previously orwherehas
$query->whereIn('language_id', $languages);
}) ->orWhereHas('specialized_fields', function($query) use ($fields) {
$query->whereIn('specialized_field_id', $fields);
})
->get();
dd($agencies);
}

Property [***] does not exist on this collection instance Laravel eloquent relationship

In my Post Model
public function user()
{
return $this->belongsTo('App\User');
}
And in the User Model
public function posts()
{
return $this->hasMany('App\Post');
}
Now I am trying to get the comments of a specific user
$user= User::where('name', 'like', '%Mat%')->first();
return $user->posts->comment;
But it shows
Property [comment] does not exist on this collection instance.
The user has many posts which therefore returns a collection, you will need to loop over this to get your comments out. I.e.
$user = User::where('name', 'like', '%Mat%')->first();
$user->posts->each(function($post) {
echo $post->comment;
});
See the documentation on Laravel Collections
I think you can try this :
$user= User::with('post')->where('name', 'like', '%Mat%')->get();
$postComment = array();
foreach($user->post as $post){
$postComment = $post->comment;
}
return $postComment;
Hope this help for you !!!
If you want to have all comments you can use the following code:
$comments = [];
$user = User::where('name', 'like', '%Mat%')->with(['post.comment' => function($query) use (&$comments) {
$comments = $query->get();
}])->first();
return $comments;
Property [comment] does not exist on this collection instance.
The above error occurs because the Posts function returns a collection. Now you will have to traverse through each element of the collection.
Since, you are returning $user->posts()->comment, I am assuming you need it in the form of an array and don't have to simply echo them out, one by one. So you can store them all in an array & then process it whatever whay you like.
$comments = array();
$user->posts()->each(function $post){
$comments = $post->comment;
}
return $comments;
For greater insight, into this collection function read:
https://laravel.com/docs/5.4/collections#method-each

laravel 5.2 if else to query database

stuck on a form that allows the user to enter a value into a choice of two fields. I can query the database using one field but want to add more range to database queries. With the following code below when i try to access the page to query it just shows me a white screen.
public function index()
{
$data = $request->all();
if(!empty($data['pstoreNum']))
{
$pstoreNum = $data['pstoreNum'];
$result = DB::table('perfumes')->where('StoreNumber','=',$pstoreNum)
->get();
return view('perfumes',compact('result'));
}
else if(!empty($data['pweekNum']))
{
$pweekNum = $data['pweekNum'];
$result = DB::table('perfumes')->where('WeekNumber','=',$pweekNum)
->get();
return view('perfumes',compact('result'));
}
}
My routes file simple calls the index function. Any help would be appreciated.
You can add query functions within your query like so
public function index(Request $request)
{
$data = $request->all();
$result = \DB::table('perfumes')->where(function($query) use ($data) {
if(!empty($data['pstoreNum'])) {
$query->where('StoreNumber', '=', $data['pstoreNum']);
}
if(!empty($data['pweekNum'])) {
$query->where('WeekNumber', '=', $data['pweekNum']);
}
})->get();
return view('perfumes',compact('result'));
}
You can then use the one query and add multiple wheres on various conditions.
https://laravel.com/docs/5.2/queries#advanced-where-clauses

Resources