Returning custom variable in Settings - Laravel Spark - laravel

I have setup Spark and I have created my custom view in Settings - Students (assume User object is actually a teacher). I have also created migration and model Student.
Now http://spark.app/settings/students returns the page successfully. At this point, I need to return data from backend. I investigated Spark\Http\Controllers\Settings\DashboardController#show - which is the method returning the 'settings' view, however this doesn't return any data to view using ->with('user', $user)
But, as mentioned in Docs, :user="user" :teams="teams" :current-team="currentTeam" already available out of the box.
Where and how does Spark returns these values to /settings? And How do I make my Student object available likewise?
Now, if I want to return my Student object to front-end, I have 2 choices.
1) edit Spark\Http\Controllers\Settings\DashboardController
2) I think Spark\InitialFrontendState is the place where Spark returns these objects user, teams, currentTeam. This approach is something I've seen for the first time to be honest and I didn't really understand how it works.
So how should I achieve in Spark, something as simple as :
return view('spark::settings')->with('student', $student); ?

Add a new route and set up your own Controller & own view
web.php
Route::get('/settings/students', 'SettingsStudentController#index');
SettingsStudentController.php
class SettingsStudentController extends Controller {
public function __construct() {
$this->middleware('auth');
}
public function index(Request $request) {
$user = Auth::user();
$student = STUDENTCLASS::whatever();
return view('yourstudentview', ['student' => $student , 'user' => $user]);
}
}

Related

how to show authenticated user data from relations

I'm trying to show the data of the authenticated user from his relation with other tables but can't get it to work, and I'm pretty new to laravel.
the user table has a relation with level table thru level_id, and the level table has a morph relation with the languages table, I'm trying to show the language of the level of the current user
here is my user model relation
public function level()
{
return $this->belongsTo(Level::class, 'level_id');
}
and my level model
public function languages()
{
return $this->morphMany(Language::class, 'langable');
}
and in the language table, I need to get back the title of 0 or 1 like
languages['0']title.
here is my controller
public function profile()
{
$user= User::with('level')->with('offers')->get();
return view('pages.user.index',compact('user'));
}
and here is how I got the auth user
{!! auth()->user()->first_name . ' ' . auth()->user()->last_name !!}
I'm trying to get this to work
{{auth()->user()->level()->languages()->title['0']}}
but it shows me this
Try {{ $user->level->languages->title['0'] }} in your index.blade file since you are passing the $user var from your controller to it. Currently you are using the user from session.
i got the answer guys it goes like this
{{Auth::user()->level->languages[0]->title}}
that'd show the level of the current user
Okay, there are a few steps you need to get done
in your controller:
public function profile()
{
$user = Auth::user(); // gets the logged in user
return view('pages.user.profile', compact('user')); // return view with $user variable
}
in your user model add:
// appends the level data to the $user model
// so every time you retrieve a user, the level data is included and accessible
// after that you can use $user->level in your view file
protected $appends = [
'level'
];
in your level model add:
// appends the languages data to the $user model
// so every time you retrieve a level, the languages data is included and accessible
// after that you can use $level->languages in your view file
protected $appends = [
'languages'
];
NOTE: In Step 3 you are retrieving multiple languages for a level. Is that correct ?
usage in view
$user->level->languages[specificLanguage]->title // if level has multiple languages
$user->level->language->title // if level has one language

laravel 5.6 Eloquent : eloquent relationship model creation issue

in my controller i create an Eloquent Model Instance passign throug a relation. The model is loaded on controller's __construct, that's why is present a $this->store and not a $store.
public function index()
{
if (is_null($this->store->gallery)) {
$this->store->gallery()->create([
'title' => 'gallery_title,
'description' => 'gallery_description',
]);
}
$gallery = $this->store->gallery;
dd($gallery);
return view('modules.galleries.index', compact('gallery'));
}
Simply if a store's gallery is not present yet, let's create it.
The first time i print out my dd() is ALWAYS null, if i reload the page the dd() show correctly my gallery model.
The things is weird for me, seems like the first time the creation is done but not ready... I can work around but why this code doesn't work the first time?
Help is very appreciate.
Relationship codes: on gallery ....
public function store()
{
return $this->belongsTo(Store::class);
}
on store...
public function gallery()
{
return $this->hasOne(Gallery::class);
}
When using the $this->store->gallery()->create() method, the original method is not hydrated with the new value, you can simply do a
$gallery = $this->store->refresh()->gallery;
OR
$gallery = $this->store->load('gallery')->gallery;
if you want to make your code cleanner you can do that in your Store Model:
public function addGallery($gallery){
$this->gallery()->create($gallery);
return $this->load('gallery')->gallery;
}
And that in your controller:
$gallery = $this->store->addGallery([
'title' => 'gallery_title',
'description' => 'gallery_description',
]);
and voila ! You have your gallery ready to be used :)
It's the lazy load part of Eloquent. basicly, when you tested for it with is_null($this->store->gallery) it sets it to that value.
when you tried to recover it again, it did not do the DB query, it just loaded the value already present (null).
after creation you need to force reload the relation:
$this->store->load('gallery');
or
unset($this->store->gallery);
or
$gallery = $this->store->gallery()->get();

Laravel 5.4 storing mass assignment model and relationship

I'm unsure of the best practice when inserting mass assignment relationships within Laravel 5.4 - I'm new to the framework. The below code is working correctly, however can you tell me is there a way to simply into one line (inserting relationships)?
I've tried to look at 'save()'and 'push()' but it's not working as expected. Would this have an impact if transactions would scale up?
I have a Listing model, with a hasOne relationship:
public function garage()
{
return $this->hasOne('App\Garage', 'post_id');
}
First of all I have some validation, then I use the following to store, which I want to simplify to one one line of code:
public function store(Request $request)
{
// Validation has passed, insert data into database
$listing = Listing::create($request->all());
$listing->Garage()->create($request->all());
}
Also if I wanted to return the data inserted, how would I do this as the following is only returning the Listing model and not the Garage relationship? Yes I know that I wouldn't do this in a real world application.
return \Response::json([
'message' => 'Post Created Succesfully',
'data' => $listing
]);
Any help is muchly appreciated
Method chaining
Your store method looks good. You could chain methods though, if you don't need the listing object itself:
public function store(Request $request)
{
// Validation has passed, insert data into database
$garage = Listing::create($request->all())
->garage()->create($request->all();
}
But if you need the listing object, it's fine as you did it before!
Returning relation models
If you want to return the garage relation model too, you can simply do that by accessing it like a normal class propery:
return \Response::json([
'message' => 'Post Created Succesfully',
'data' => [$listing, $listing->garage]
//Access collection of garage relation ship
]);

Fluently updating an existing one to one relationship with Eloquent in Laravel 5

I have a one-to-one relationship between my User model and an additional UserInformation model in which I store additional needed information which would bloat the "normal" user table.
I set up my models like this:
# User.php
public function information()
{
return $this->hasOne(UserInformation::class);
}
# UserInformation.php
public function user()
{
$this->belongsTo(User::class);
}
I have a profile page where the User can update information from both tables.
The view has inputs like this:
<input name="email"> // is a field in the users-table
<input name="information[size]"> // is a field in the users-information table
I read in different locations that I should be able to save both my User model and its relation in with:
$user->fill($request->all())->save();
But this throws the following error:
preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
So my current solution looks like this:
auth()->user()
->fill($request->except('information'))
->save();
auth()->user()
->information
->fill($request->input('information'))
->save();
That works very good but doesn't look good in my opinion. So my question is: how can I clean that code up and save both in one go?
Have you tried including this
protected $guarded = array('information');
in your User.php model file
and then
auth()->user()
->fill($request->all())
->information->fill($request->input('information'))
->save();
I think your current solution looks fine, but if you want, you could always extract it out to your own custom method in your User model.
public function saveWithInformation($attributes)
{
$this->fill($attributes)->save();
$this->information->fill($attributes['information'])->save();
}
Then you can just call:
auth()->user()->saveWithInformation($request->all());
Since I was looking for a pretty flexible solution I came up with this function which I implemented into my User model (but it could also be included in a BaseModel)
public function fillWithRelation(array $request)
{
foreach ($request as $key => $value)
{
if (is_array($value) && method_exists($this, $key))
// check if the value is an array and if a method with the name of
// the key exists (which would be the relationship
{
$this->{$key}->fill($value);
unset($request[$key]);
}
}
return $this->fill($request);
}
This is definitely working if you include the information for a hasOne relationship like posted in my question.

Data getting lost while passing from controller to view in Laravel

In one of my controller, I'm passing the result obtained from an Eloquent query to a view. But no matter how I pass the result to the view, I'm not getting the result in the view.
The controller:
class ProductCategoriesController extends BaseController
{
public function __construct()
{
parent::__construct();
// Add location hinting for views
View::addNamespace('product-categories', app_path() . "/MyVendor/ProductsManager/Views/admin/product-categories");
}
public function index()
{
$categories = ProductCategory::all();
return View::make('product-categories::index')
->with('title', 'All Product Categories')
->with('categories', $categories);
}
...
}
If I view the dd the value of $categories inside the index controller, I get the proper Eloquent collection, like following:
object(Illuminate\Database\Eloquent\Collection)[655]
protected 'items' =>
array (size=1)
0 =>
object(MyVendor\ProductsManager\Models\ProductCategory)[653]
protected 'table' => string 'product_categories' (length=18)
protected 'guarded' => ...
But if I dd the value of $categories inside the index view, I get an empty Eloquent collection, like following:
object(Illuminate\Database\Eloquent\Collection)[655]
protected 'items' =>
array (size=1)
0 => null
I am doing similar approach in other controllers and they work fine. I don't know what the problem with this controller is. I have been using Laravel for quite some time now and never had this problem before. Maybe I'm missing something, or there's something wrong with the recent package updates. Whatever it is, it's driving me crazy. Any ideas on what the problem might be?
P.S. I'm using Laravel Framework version 4.2.6
I finally figured out what the problem was. I was using robclancy/presenter package to wrap and render objects in the view. For it, the model had to implement a PresentableInterface interface. Implementing the interface required the method to have a getPresenter method. I had added the getPresenter method in my model, but I forgot to return the presenter from that method. Returning the presenter solved the problem.
The code inside the getPresenter method is the code that I forgot to write.
public function getPresenter()
{
return new ProductCategoryPresenter($this);
}
Thank you guys for trying to help.

Resources