better understanding about #foreach on laravel - php

i just want to ask how exactly #foreach in laravel works for examply code like this
#foreach ($users as $user)
#endforeach
i know $users value can be obtained from controller like this:
public function show()
{
$users = users:find($id);
return view('user_tab', compact('users'));
}
but i saw some tutorial on site that do #foreach like :
#foreach ($user->posts as $post)
#endforeach
what's posts without $ stand for ?? i just dont know. i do already read laravel documentation about this on here https://laravel.com/docs/8.x/blade but still cant understand it can someone explain it to me? thx for advance

$user->posts
Here 'posts' represents a model relationship. Go to your User model and you will find a function like this:
function posts() {
return $this->hasMany(Posts::class);
}
This represents that a User can have multiple posts. You can directly get all the post of an user by calling this function once you get a user instance.
Hence in your code it is fetching all the posts of the specific user by $user->posts and then iterating over it in #foreach loop.

if in your controller you call user with relation then you can access the related enter code here` like this

Related

Laravel: When I pass a model to a controller it is always null. Why?

I'm trying to change my ways in Laravel, but I find it quite frustrating
Normally, in a controller I'd write something like this
public function edit($id) {
$question = Question::findOrFail($id);
return view('question.edit', compact('question');
}
This obviously works. In the HTML the route that calls this is {{ route('question.edit', $question->id) }}. Now I want to use the method it is written by Artisan when you create the controller. If I do:
public function edit(Question $question) {
return view('question.edit', compact('question');
}
This doesn't work (of course I'm changing the blade directive to {{ route('question.edit', $question) }}), this always passes an empty Question model, it doesn't have id or any of the other fields that were accessible in the blade file. If I do a dd() in the blade file, it'll show the correct model, when passed to the Controller is empty.
What am I doing wrong?
You need to match your type hinted variable name to the name of the route parameter if you want Implicit Model Binding to work, otherwise you are just asking for a dependency and it will inject a new instance of that model:
// vvvvvvvv
Route::get('question/{question}/edit', 'YourController#edit');
// vvvvvvvv
public function edit(Question $question)

Laravel 5.8 Eloquent querying

I know all the Eloquent model querying is in the Laravel documentation and I have read through them to figure this out but can't seem to work my way around it. I am building a recipe application, and I want to get access to a particular profile picture of a user based on an uploaded recipe.
I have a grid of recipes that have been uploaded by various users. The User and Recipe model are below.
User Model
public function recipes()
{
return $this->hasMany('App\Recipe');
}
Recipe Model
public function user()
{
return $this->belongsTo('App\User');
}
In my recipe grid, I have the following code in a recipe card.
Index Blade/View
#foreach($recipes as $recipe)
<img class="recipeProfilePic" src="/storage/profile_pictures/{{What goes here}}" alt=""><a
href="{{ route('user', $recipe->user_id) }}">
<small>{{$recipe->author}}</small>
</a>
#endforeach
Through the $recipe I can access the name of the creator of that particular recipe like this $recipe->author. I am trying to get access to this specific users profile photo too. I want to get something like this $recipe->author->profile_pic. (profile_pic is a column in my users table).
How would I go about solving this problem in a simple way? I'm a newcomer to coding and am still working on solving these problems myself. Thank you!
You can do it like this:
$recipe->user->profile_pic
You can change the model by rename user to author like this:
public function author()
{
return $this->belongsTo('App\User');
}
or changing view (blade) like this:
#foreach($recipes as $recipe)
<img class="recipeProfilePic" src="/storage/profile_pictures/{{What goes here}}" alt=""><a
href="{{ route('user', $recipe->user_id) }}">
<small>{{$recipe->user->profile_pic}}</small>
</a>
#endforeach

Laravel how to take from another table?

I have a table called "logs" with custom column "auth_id" and i have another table called "users" with same column name "auth_id" and column "username".
How can i take it from "logs" with "logs.auth_id" and get username by "users" table?
Now i'm getting results by:
$match->messages = DB::table('logs')->where('match_id', '=', $match->match_id)->get();
Blade:
#foreach ($match->messages as $message)
{{ $message->auth_id }}:
{{ $message->message }}
Example: Now i'm getting AUTH5556 with {{ $message->auth_id }} but i need to get USERNAME from "users" table by {{ $message->auth_id }}
Don't use joins, this is the whole reason for using something like laravel (eloquent). You need to define a relationship between your models.
On your user model you would define a method
public function logs()
{
return $this->hasMany(Log::class);
}
On your log model
public function user()
{
return $this->belongsTo(User::class);
}
Now you need to make sure on your logs table you have a user_id column.
Now you can simply get the log for example
$log = Log::find($id);
And you can retrieve any information about the user who owns that log, for an example in a blade file.
{{ $log->user->username }}
To get reverse information you need to iterate through the results as the user can have many logs. Eg:
$user = User::find($id);
Then you'd do something like this in your blade
#foreach($user->logs as $log)
{{ $log->column_on_log_you_want }}
#endforeach
You also need to look into eager loading.
This is what makes laravel so clean and nice to use.
Read through the documentation
You need to use JOIN in your query to get username from users table. Here is the link to Laravel manual

Random images in laravel

I have a database table called random_img. Inside are 10 rows for 10 images.
I will be pulling the images from public/images/random
I want to use the database so I can set the loop to Random take(1). I want to use in my hero images. (New image on every page refresh)
Where would I put my database query so I can use it Globally? Or how can I use my RandomImgsController so it is being used globally?
I created a route file, so I can use it as an include where needed.
Route:
Route::post('/layouts/inc/random-img','RandomImgsController#randomimg')->name('random-img');
Include:
#include('layouts.inc.random-img')
Inside Include:
#foreach ($randomimg as $rand)
<span class="hero-image">
<img src="/images/random/{{$rand->file_name}}" class="img--max--hero blur-img">
</span>
#endforeach
RandomImgsController: (Where should this go so I can use globally)
public function randomimg()
{
$randomimg = DB::table('randomimg')->orderBy(DB::raw('RAND()'))->get();
return view('random-img',compact('randomimg'));
}}
This is what I want to achieve on every page of my website:
#php
$randomimg = DB::table('randomimg')->orderBy(DB::raw('RAND()'))->get()->take(1);
#endphp
#foreach ($randomimg as $rand)
<span class="hero-image">
<img src="/images/random/{{$rand->file_name}}" class="img--max--hero blur-img">
</span>
#endforeach
What would be a cleaner way to do this?
Update:
I can access the images DB in all views now, but I have an issue.
In my App\Http\ViewComposer\ImageComposer.php file I have this:
public function compose(View $view)
{
$view->with('foo', Image::inRandomOrder()->get()->take(1));
}
In any view I can use {{$foo}} to get a random row from my images table, but the data comes in a string like this:
[{"id":10,"alt":"Image Alt Tag","title":"Image Title","file_name":"10.jpg"}]
When I try to only grab individual columns like this {{$foo->file_name}}
I get the error:
Property [file_name] does not exist on this collection instance.
How can I grab individual columns like this: {{$foo->alt}} , {{$foo->title}} and {{$foo->file_name}} then cleanly output them in my view? Example, I need {{$foo->file_name}} to render like this: 5.jpg.
Update 2:
I figured it out. Have to use #foreach since I'm using the get() method.
#foreach($foo as $f)
{{$f->file_name}}
#endforeach
Would still like to know if there is a way to do it without the get() method. This will work though.
First of all you can't #include a route in a blade template. What you would actually do is send an AJAX request from your blade template to the route you created to retrieve the random images. However...
It sounds like a controller is the wrong place for the logic in this situation.
Assuming you have an associated Eloquent model for your table, a simple option could be to define a method on your RandomImage model (could probably just be called Image).
This way, you can just use your Image model to generate and pass a random image to any view you would like. Then there is also no need to query for every image on each page reload. You would only ever be querying for one image per request.
Imagine if the code in your view could look like this:
<span class="hero-image">
<img
src="{{ $image->url() }}"
class="img--max--hero blur-img" />
</span>
And maybe this belongs in a home page for example, which is what it sounds like you're trying to do. So maybe you have a route like this:
Route::get('/', function () {
$image = App\Image::random();
return view('home', compact('image');
});
You could achieve this using a Query Scope on your Image model:
public function scopeRandom($query)
{
return $query->inRandomOrder()->first();
}
Edit
If you want this to be used across many, or even all views in your website you can use a View Composer: https://laravel.com/docs/5.6/views#view-composers
Your compose method would look like this:
public function compose(View $view)
{
$view->with('image', Image::random());
}
And the View Composer would be registered either in your AppServiceProvider or in a new provider such as ComposerServiceProvider. Inside of the boot method you need:
public function boot()
{
// Using class based composers...
View::composer(
'*', 'App\Http\ViewComposers\ImageComposer'
);
}
Where the * says that you want this composer to be applied to all views.

Framework Laravel: view records using specific condition

I have never learnt this framework. As a beginner, I have to modify/add a link in the existing software which is made by some professional team. Could you people can help me out of this situation?
There is a function that shows the records on the main page public function index(). It has return View::make('Titles.Index')->withType('movie');. But I have to add a parameter that shows only english movies having field name language can have 'en' as its value. Would you suggest what needs to be done that it will show up using this condition? I have tried return View::make('Titles.Index')->with('language','en'); but it shows error on the main page.
Basically, index is a controller method that handles the view for your specific route.
Inside the controller method, you can filter the movies and pass a collection to the view. Considering that you have a model called Movie with namespace App\Movie so you can do something like:
public function index() {
// Returns a collection with movies where language field
// is equal 'en'.
$moviesEn = App\Movie::where('language', 'en')->get();
return View::make('Titles.Index')->with('moviesEn', $moviesEn);
}
This code injects the moviesEn variable inside your Titles.Index view. So there you can use it:
#foreach ($moviesEn as $movie)
{{ $movie->title }}
#endforeach

Categories