Laravel get property of non object - php

When I try to determine if an object is empty it's telling me:
Trying to get property of non-object
I'm doing it like this:
$lastTicket = Auth::user()->ticket->last()->ticketid;
if($lastTicket->isEmpty())
{
$lastTicket = 0;
}
Obviously Auth::user()->ticket->last(); isn't a record yet. How should I do this? I'm working with Laravel.

You need to check that collection not empty before get the property:
if(Auth::user()->ticket->last()->isEmpty())
{
$lastTicket = 0;
}
else
{
$lastTicket = Auth::user()->ticket->last()->lastId;
}
In short way:
$lastTicket = !Auth::user()->ticket->last()->isEmpty() ? $lastTicket = Auth::user()->ticket->last()->lastId : 0;

First of all have a look here if can be a solution at your problem. And anyway if you're trying to load a relation you should look at the official documentation:
Dynamic Properties
Eloquent allows you to access your relations via dynamic properties. Eloquent will automatically load the relationship for you, and is even smart enough to know whether to call the get (for one-to-many relationships) or first (for one-to-one relationships) method. It will then be accessible via a dynamic property by the same name as the relation. For example, with the following model $phone:
class Phone extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
$phone = Phone::find(1);
Instead of echoing the user's email like this:
echo $phone->user()->first()->email;
It may be shortened to simply:
echo $phone->user->email;

The right answer was:
$lastTicket = !Auth::user()->ticket->last() ? Auth::user()->ticket->last()->ticketid+1 : 0;
because if it's empty it will return 0 as default.

Related

How to check if row is soft-deleted in Eloquent?

In Laravel 5.1 is there a nice way to check if an eloquent model object has been soft-deleted? I'm not talking about selecting data but once I have the object e.g. Thing::withTrashed()->find($id)
So far the only way I can see is
if ($thing->deleted_at !== null) { ... }
I do not see any relevant method in the API that would allow for example
if ($thing->isDeleted()) { ... }
Just realised I was looking in the wrong API. The Model class doesn't have this, but the SoftDelete trait that my models use has a trashed() method.
So I can write
if ($thing->trashed()) { ... }
In laravel6, you can use followings.
To check the Eloquent Model is using soft delete:
if( method_exists($thing, 'trashed') ) {
// do something
}
To check the Eloquent Model is using soft delete in resource (when using resource to response):
if( method_exists($this->resource, 'trashed') ) {
// do something
}
And finally to check if the model is trashed:
if ($thing->trashed()) {
// do something
}
Hope, this will be helpful!
For those seeking an answer on testing environment, within laravel's test case
you can assert as:
$this->assertSoftDeleted($user);
or in case it's just deleted (without soft deleting)
$this->assertDeleted($user);
This is the best way
$model = 'App\\Models\\ModelName';
$uses_soft_delete = in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($model));
if($usesSoftDeletes) {
// write code...
}
This worked for me
$checkDomain = Domain::where('tenant_id', $subdomain)->withTrashed()->first();
if($checkDomain->trashed()){
return redirect()->route('domain.not.found');
}else{
return view('frontend.' . theme() . '.index');
}

How to solve Laravel select queries conflicting with the $appends property on models?

I have a situation where I need a specific attribute accessor appended to one of my models automatically:
class Mission extends Eloquent {
protected $appends = ['launch_date_time'];
public function getLaunchDateTimeAttribute() {
return ($this->attributes['launch_approximate'] == null) ? $this->attributes['launch_exact'] : $this->attributes['launch_approximate'];
}
}
As you can see, this launch_date_time property is dependent on two other fields of my model that are actually in my database.
However, I now want to perform a query where only a certain number of fields are returned, as this is going to be sent over AJAX multiple times and I would rather use as few resources as possible:
// AJAX GET
// missions/all
public function all() {
$allMissions = Mission::with('featuredImage')->get(['mission_id', 'name', 'featured_image']);
return Response::json($allMissions);
}
The issue here is that I no longer need the launch_date_time attribute, so I have excluded it, **in doing so, my AJAX request does not work successfully:
Undefined index: launch_approximate on line 78 of H:\myproj\app\models\Mission.php
This is clearly because my model is attempting to append launch_date_time, of which launch_approximate is a dependency of. If I include all the required dependencies, all of them any my attribute that I want to append appear:
$allMissions = Mission::with('featuredImage')->get(['mission_id', 'name', 'featured_image', 'launch_approximate', 'launch_exact', 'launch_date_time']);
This is undesirable. Is there a solution where I can keep both setups?
The reason it is not working is because you are not retrieving the required fields from the database in the get method on your query. That is why you can't access launch_exact and launch_approximate because they are not set in the instance of your model.
So to make it work like you want. You would have to check if launch_exact and launch_approximate are set before you access them.
public function getLaunchDateTimeAttribute() {
if(isset($this->attributes['launch_approximate']) && $this->attributes['launch_exact']) {
return ($this->attributes['launch_approximate'] == null) ? $this->attributes['launch_exact'] : $this->attributes['launch_approximate'];
}
return null;
}
You can also set a whitelist with the $visible property and a black list with $hidden inside your model to not show certain attributes when outputing to json or a array take a look at the docs: http://laravel.com/docs/5.1/eloquent-serialization#hiding-attributes-from-json

Is it possible to use models in laravel routes without static?

For example I need to return comments. I already have a method for this in my model. Is it possible to do something like this?
Route::get('/comments/{page}', function($page) {
$comments = Comments::get($page);
return Response::json($comments);
});
Or do I need to create a facade for each model?
Typically, comments would be associated with a page via an Eloquent relationship, which would allow something like this:
return Response::json($page->comments);
Check Defining A Query Scope on Laravel website:
// In Comments Model
public function scopeGetMessage($query, $page)
{
// You can use $query->where(...)
// return the query for chaining
// You can use $this->where(...)
// Or just return the thing you want
}
Now you may call it like:
$comments = Comments::getMessage($page);

Yii Framework - How do I get a different value for a field?

I have a table with a field called vat_free. So my model was created with a property $vat_free. Its value can be 0 or 1.
I want my view to show No or Yes, instead of 0 or 1. I can do it creating a getter like getVatFree(), but it seems like a messy solution, because then I'll have two properties to the same field, even though it would serve different purposes.
So how can I use only the original property $vat_free? Couldn't I modify its getter?
Creating method
public function getVatFreeString(){
return $this->vat_free ? 'Yes':'No';
}
Is proper solution, it's not messy.
You could do like
$vat_free = YES or NO
but right before save this object you would override object class with beforeSave() method like following:
beforeSave(){
if($this->vat_free = YES){
$this->vat_free = 1
}else{
$this->vat_free = 0;
}
}
and override afterFind() to do the reverse(for beforeSave()) translate. But this is even messy and will not work if u do bulk save or retrieve.
I see 2 solutions.
Go with what you have said getVatFree(), this is whole purpose of OOP encapsulation.
Instead of making 1 or 0 in db, do Y or N values, you can use them in both places without problems.
In your model, create a new field that will be used for display purposes only.
class User extends CActiveRecord
{
public $displayVatFreeFlag;
public function rules() { ... }
public function afterFind()
{
$this->displayVatFreeFlag = ($this->vat_free ? 'Yes':'No');
}
}
Then, in your field, display the field as normal.
Vat free : <?php echo $model->displayVatFreeFlag; ?>

I would like to know if an object is in my Doctrine Collection

I'm working on Symfony 1.4 with Doctrine 1.2 and I have some problems.
I have created one Doctrine Collection of my Products like this :
$oProductCollection = new Doctrine_Collection('Products');
And I add some product in :
$oProductCollection->add($oMyProduct);
Then I want to know if a product is already in my Collection. Because if I add my product twice, that overwrite my old version...
I found "contains" function but I can't give my product object directly and I don't know what the key is...
Could you help me please ?
You can set the keyColumn by
//set the id column as key
$oProductCollection = new Doctrine_Collection('Products', 'id');
Then you can use $oProductCollection->contains($oMyProduct->getId()); to check whether $oMyProduct is already in your Collection.
Now you are able to write
if ($oProductCollection->contains($oMyProduct)){
echo "Its already in";
}else{
$oProductCollection->add($oMyProduct);
}
Another alternative. Index your collection by id, and just check if it exists. It should be pretty fast. Take a look at the docs.
Something like:
$id = $oMyProduct->getId();
if (!empty($oProductCollection[$id])){
...
}
You should implement a method Produits::equals(Produit $p) check every object of the collection using a loop.
foreach ($oListeProduit as $p) {
if ($p->equals($produit)) {
return true;
}
}
return false;
You have to use the second parameter of the Doctrine_Collection constructor:
public function __construct($table, $keyColumn = null)
So:
$oProductCollection = new Doctrine_Collection('Products', 'id');
And then contains with an id will work.
Edit: grilled :(

Categories