Get specified properties of a model all at once in Laravel - php

I want to pass some user data to a view so it can be displayed in the profile page. There is quite a lot of it but I don't want to just pass everything, because there are some things the view shouldn't have access to. So my code looks like this:
return view('profile', [
'username' => Auth::user()->username,
'email' => Auth::user()->email,
'firstname' => Auth::user()->firstname,
'country' => Auth::user()->country,
'city' => Auth::user()->city->name,
'sex' => Auth::user()->sex,
'orientation' => Auth::user()->orientation,
'age' => Auth::user()->age,
'children' => Auth::user()->children,
'drinking' => Auth::user()->drinking,
'smoking' => Auth::user()->smoking,
'living' => Auth::user()->living,
'about' => Auth::user()->about,
]);
My question is: Can this be written shorter/simpler?
Thanks!
EDIT:
I don't want this: {{ Auth::user()->firstname }} because there is a logic in a view, which is bad - I think, there should be just plain variables to be displayed, in view, not anything else.
So I'm looking for something like:
return view('profile', Auth::user()->only(['firstname', 'email', ...]));

You could create by yourself a method named like getPublicData and then return all those properties you need.
...
public function getPublicData() {
return [
'property_name' => $this->property_name
];
}
...
... and then use it in your controller/views. Maybe it's not an optimal solution, but you can isolate this thing in the model and avoid too much code in the controller.
Another advanced approach could be the override of the __get method. However, I am not the first in this case.
Hope it helps!

You don't need to pass these variable to the view, you can directly access them in the view using blade
<h1>{{ Auth::user()->username }}</h1>

Related

Can't access specific route in Laravel

When I return from a function with a view and a compact table:
$table = (new \Okipa\LaravelTable\Table)->model(Expense::class)->routes([
'index' => ['name' => 'admin.expenses.index'],
'edit' => ['name' => 'admin.expenses.edit'],
'destroy' => ['name' => 'admin.expenses.destroy'],
])->tbodyTemplate('bootstrap.expenses.tbody')
->query(function($query) use($user){
$query->select("expenses.*");
// $query->join('projects',"projects.id","=","expenses.project_id");
// $query->addSelect('projects.name as project');
$query->where('user_id', $user->id)->whereNull('travel_id');
});
return view('backend.expenses.index', compact('table'));
Laravel displays this error:
Return value of Okipa\LaravelTable\Table::render() must be of the type string, object returned (View: /home/armand/Desktop/GSurvey/expenses/resources/views/vendor/laravel-table/bootstrap/table.blade.php)
The index blade is where it supposed to be and in the view I have just a simple line to display the table: {{ $table }}
Can anyone extend a helping hand, maybe I am missing something?
Thank you in advance,
Kind regards,
Armand Camner

Laravel 7.2.* Language string parameter is not translating with the given value

I am having a weird problem working with language parameters in laravel. It is not being replaced with the variable but outputting the entire key.
admin.php
return [
...
'delete_title' => 'Delete :item',
...
// user section
'user' => [
'user' => 'User',
...
],
];
view.blade.php
// this won't work
{__('admin.delete_title', ['item', 'User'])}}
// this won't work
{__('admin.delete_title', [':item', 'User'])}}
// this won't work
{__('admin.delete_title', ['item', __('admin.user.user')])}}
// this won't work
{__('admin.delete_title', ['item', __('admin.user.user')])}}
I think you should to pass correct args to translate function try:
{__('admin.delete_title', ['item'=>'User'])}}
You need to pass parameters as array, so:
{{ __('admin.delete_title', ['item' => __('admin.user.user')]) }}
You have typo in
'delete_title => 'Delete :item', // missing '
fixed:
'delete_title' => 'Delete :item',

Laravel phpunit test nested eager loading

I have this nested relation im abit unsure how i assertJson the response within the phpunit test.
FilmController
public function show(string $id)
{
$film = Film::with([
'account.user:id,account_id,location_id,name',
'account.user.location:id,city'
])->findOrFail($id);
}
FilmControllerTest
public function getFilmTest()
{
$film = factory(Film::class)->create();
$response = $this->json('GET', '/film/' . $film->id)
->assertStatus(200);
$response
->assertExactJson([
'id' => $film->id,
'description' => $film->description,
'account' => $film->account->toArray(),
'account.user' => $film->account->user->toArray(),
'account.user.location' => $film->account->user->location->toArray()
]);
}
Obviously this isnt working because its returning every column for the user im a little unfamiliar with how you test nested relations with the code you need so im unsure with a toArray can anyone help out?
Testing is a place where you throw DRY (don't repeat yourself) out and replace it with hard coded solutions. Why? simply, you want the test to always produce the same results and not be bound up on model logic, clever methods or similar. Read this amazing article.
Simply hard code the structure you expect to see. If you changed anything in your model to array approach, the test would still pass even thou your name was not in the response. Because you use the same approach for transformation as testing. I have tested a lot of Laravel apps by now and this is the approach i prefers.
$account = $film->account;
$user = $account->user;
$location = $user->location;
$response->assertExactJson([
'description' => $film->description,
'account' => [
'name' => $account->name,
'user' => [
'name' => $user->name,
'location' => [
'city' => $location->city,
],
],
],
]);
Don't test id's the database will handle those and is kinda redundant to test. If you want to check these things i would rather go with assertJsonStructure(), which does not assert the data but checks the JSON keys are properly set. I think it is fair to include both, just always check the JSON structure first as it would likely be the easiest to pass.
$response->assertJsonStructure([
'id',
'description',
'account' => [
'id',
'name',
'user' => [
'id',
'name',
'location' => [
'id',
'city',
],
],
],
]);

[name]Controller and its behaviors do not have a method or closure named "createReturnableUrl"

Working in Yii, i get the error of
SystemManagementController and its behaviors do not have a method or
closure named "createReturnableUrl"
I can not find anything to solve it. it happened right after I added this:
array(
'class' => 'CButtonColumn',
//'viewButtonUrl' => '$this->grid->controller->createReturnableUrl("view",array("id"=>$data->id))',
'updateButtonUrl' => '$this->grid->controller->createReturnableUrl("update",array("id"=>$data->id))',
'deleteButtonUrl' => '$this->grid->controller->createReturnableUrl("delete",array("id"=>$data->id))',
//'deleteConfirmation' => Yii::t('app', 'Are you sure to delete this item?'),
),
to :
<?php
//The following lines needs to be moved to the controller to sepparate the view from the controllers.
$model = new CActiveDataProvider('User');
//The following line should be set by the controller. Containing the names of the colums in a chosen language.
/**/
$colums = array(
'login',
'name_first',
'name_last',
//'password',
'email',
'is_active',
//'sortorder',
array(
'class' => 'CButtonColumn',
//'viewButtonUrl' => '$this->grid->controller->createReturnableUrl("view",array("id"=>$data->id))',
'updateButtonUrl' => '$this->grid->controller->createReturnableUrl("update",array("id"=>$data->id))',
'deleteButtonUrl' => '$this->grid->controller->createReturnableUrl("delete",array("id"=>$data->id))',
//'deleteConfirmation' => Yii::t('app', 'Are you sure to delete this item?'),
),
);
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model,
'columns' => $colums,
'filter' => $model->model)
);
?>
when I remove that piece of code, there is not problem, everything works, but when I add that line it gives me the error.
I use that line in a different class as well and there I dont get the problem, how can I get rid of this?
It looks like the controller does not know about createReturnableUrl. From what I googled that is a behavior of yii that you can attach, are you sure you attached the behavior properly for the SystemManagementController? See if all the other controller that work with the same code have that behavior attached, maybe this one does not.

Symfony FORMS : diference between {'model' => $this->getRelatedModelName('model')} and {'model'=>'model'} in setWidgets

I've been doing the SYMFONY jobeet tuto(day 10) and once in the FORMS section, I found that some times we use :
'category_id' => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('JobeetCategory'), 'add_empty' => false)),
and sometimes we use simply
'jobeet_affiliates_list' => new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'JobeetAffiliate')),
Can anyboody explain to me WHY? and HOW is it working ?
why ,sometimes,do we use getRelatedModelName?? and why somtimes 'model' => 'myModel'???
Pretty much same thing, but, you can only use getRelatedModelName when there's a relation between the current form's model and the model you need in your widget. For example, if there's a relation defined between Article and Category, you can use getRelatedModelName('Category') in ArticleForm (usually a relation is defined).
In both cases (when a relation exists/does not exist) you can just write the model as a string 'model' => 'JobeetAffiliate'. I usually do that.

Categories