Model extra calculated attribute get removed when we pass model object to any other function - laravel

I am calculating extra attribute and assigning that attribute to the Eloquent model. And I am passing that object to other function which accepts that model object only but inside that function, I am not able to access extra value which I have calculated before.
Here is my code.
$order = Order::find(201);
$order->setAttribute('redemption_end_date','anydate');
Now I am passing this order object to other function which accepts an only order model object.
function printOrder(Order $o){
dd($o->redemption_end_date);
}
So inside that function when I am trying to access that attribute which I have calculated before, it shows me as null.
How can I pass the object without losing data?

Related

Conditionally assign Laravel's controller values on Construct method

I work with a Laravel porject that uses an array of Model attributes to show it on the view. Unlike most Laravel prokects where do you send a set of data to the view and you choose how to show it on our project that's defined on a Controller's variable.
This variable ($showFields) expects an array of Model's atributes and the values are shown on the view.
The thing is that I need to adapt the shown atributes based on one atrubute's id (vendor_id). My idea is, based on the vendor_id assign one array of attributes or another.
I've been trying with the Controller's constructor method but it's not working as when it's called seems like it does not have the values yet. Is this even possible?
This is the controller's code:
protected $showFields = []; // This is the variable that tells the view what attributes to show
protected $vendorInformation = [...];
protected $noVendorInformation = [...];
public function __construct(QuoteService $quoteService)
{
parent::__construct();
$this->quoteService = $quoteService;
if($this->vendor_id === xx){
array_push($this->showFields, $this->noVendorInformation);
} else {
array_push($this->showFields, $this->vendorInformation);
}
}
I'm working with Laravel 5.7

Laravel mutators on specific situations

As I understand, mutators change your attribute on save function (create or update). Can I make mutator just for atrribute display to users, but leave default values on save function ?
In Eloquent Model when you do this:
public function getSomeNameAttribute($value)
{
return ucfirst($value);
}
That ^ will mutate the value for showing it later in views and it won't affect what is stored in DB table.
And also if you use a setter setSomeNameAttribute($value) you can pull the actual value from db table with:
$model->getOriginal('attribute_name'); // Laravel V. ^5.*
or
$model->getRawOriginal('attribute_name'); // Laravel V. ^8.*

why is $this->field not always returning a value inside laravel custom attribute model

I have a custom attribute inside my model.
if I try to get the value of i.e $this->id it works but if I add a new column to that model and call it $this->new_column it returns empty even though it has a value. So in order to retrieve it, I have to then initialise the model again inside the custom attribute.
$model = MyModel::find($this->id);
just so I can access $model->new_column
public function getCustomColumnDataAttribute(){
Log::info($this->id); //returns the value
Log::info($this->new_column); //doesn't return the value
$model = MyModel::find($this->id);
Log::info($model->new_column); //returns the value
}
I find it a waste to always initialise the model again just so I can access the values. Or am I missing something here with how $this works inside the model function?

Laravel 5 - Limiting Eloquent Where Parameters When Using Request Object Data For Get

I have controller functions that look like:
public function get(Request $request){
return json_encode($this->users->get($request->all));
}
where $this->users references a repository for my User model. Inside of this repository, I have a function that looks like:
public function get($request){
return User::where($request)->get()->toArray();
}
I can dynamically pass in any number of parameters to search on through my HTTP request with the above code without having to explicitly state the column names.
This works well as long as all the parameters passed in through the request are valid column names. It will error out if I pass in a parameter that is a not valid table column.
I have the protected $fillable array defined in each of my models corresponding to my repositories.
Is there anyway to enforce what can be passed into the where() method above so that only valid columns defined in the $fillable array in my model are ever passed in?
For example, let's say I have a users table with columns (id, name, description). The GET URL I pass in looks like:
GET /user?name=mike&description=skinny&age=45
There are three parameters in the URL above, but only two of them are valid column names. I would like the age parameter to be automatically taken out. In my current code, the above URL will return an error response since the age column does not exist.
You can use array_only() helper:
return User::where(array_only($request, $this->fillable))->get()->toArray();
It will filter $request and will keep only key/value pairs which are in the $fillable array.
If this code is not in a model, change $this->fillable to appropriate variable or method call.
I wrote a package for doing this kind of filtering for models. It will allow you to filter based on User::filter($request->all())->get(); while defining each possible column's where() constraint.
https://github.com/Tucker-Eric/EloquentFilter
Try doing something like this:
public function get(Request $request)
{
$user = new User();
return User::where(
$request->only($user->getFillable())
)->get()->toArray();
}
By creating an instance of User you can then access it's fillable properties using getFillable(). By passing this list into $request->only(...) you can restrict the values you pull out to only those that are in your fillable array. Hopefully that should mean only fillable values are considered as part of your query.
Hope it helps.

Laravel — How to get string value from object via model method?

I have model House with relation hasMany HousePhotos.
I try get link to main photo from table house_photos.
class House extends Model
{
public function photos(){
return $this->hasMany('app\HousePhoto');
}
public function get_main_photo(){
return $this->photos()->where('main', true);
}
}
Controller:
$house=House::find(1);
In View i use
{{$house->main_photo()->link}}
and got error.
When i use
{{$house->main_photo()}}
i got object. How to get string value of link to photo?
First of all you need to understand the difference between the Builder object and the Collection object.
As it is now, function get_main_photo returns a Builder object (actually a Relation object, which contains a Builder).
On these objects you can call function get() to finish the query and get the results. In this case you will get a Collection object, which you will be able to iterate.
Alternatively, in this case you seem to only have one 'main photo' per house, so instead you can call first():
public function get_main_photo(){
return $this->photos()->where('main', true)->first();
}
This will return the single associated model, on which you will be able to access ->link (if the model was found).
Remember at any point while debugging you can call the convenient dd function (which dumps the object passed as parameter and terminates the applicacion) to see what type of object you are dealing with, and all its attributes.

Resources