Redirecting to view files - laravel

just wanted to firstly note is that this works fine when I have the redirects within their own retrspective functions.
Essentially, I create a Project. Within a Project I can make many types of Documents. Relationships are all set up appropiately.
So within a Project I have links to different documents which can be created. These are like
<li>{!! link_to_route('projects.document.create', 'Some Document', array($project, 'someDocument')) !!}</li>
The route is like this
Route::get('projects/{projects}/document/{name}', array('as' => 'projects.document.create', 'uses' => 'DocumentController#create'));
And then in my DocumentController I do this
public function create(Project $project, $name)
{
$this->redirectResult($project, $name);
}
The redirectResult function essentially checks to see if the selected document (in this case someDocument) has been created before (A project can have many documents, but only one of each type).
If the document has never been created for the project, it shows the create view for that document. If it has been created before it shows the edit view. This is the function
public function redirectResult(Project $project, $name) {
$selectedDoc = Document::where('project_id', '=', $project->id)
->where('name', '=', $name)
->first();
if(!$selectedDoc) {
return View::make($name.'.create', compact('project'));
}
else {
return View::make($name . '.edit', compact('project', 'selectedDoc'));
}
}
Now when I select a document, I end up on a blank page. The url is correct, no errors or anything, simply a blank page. The strange thing is when I do it the old way (which should act the same as the above)
it works. The old way is exactly the same as above, but my create function is like this instead
public function create(Project $project, $name)
{
$selectedDoc = Document::where('project_id', '=', $project->id)
->where('name', '=', $name)
->first();
if(!$selectedDoc) {
return View::make($name.'.create', compact('project'));
}
else {
return View::make($name . '.edit', compact('project', 'selectedDoc'));
}
}
So the only different is that the view making code is directly within the function, rather than calling a function that has this code. I wanted to put all this repeat code in its own function so I do not
have to repeat it for every document controller function.
Is there any reason why my new way takes me to a blank page? Just to rule out the obvious, I do have the folders containing the view files set up correctly. So for the above example within the views folder
I have a folder called someDocument and within it I have edit.blade.php.
Any information as to why this might be occuring appreciated.
Thanks

Er... you must return the function.
public function create(Project $project, $name)
{
return $this->redirectResult($project, $name);
}

Related

Relationship with paginate

I need to create a dynamic link to take the user to the last page of the laravel page. For example, if there is a pagination, I need to include lastPage () at the end of the url www.site.com/forum/slug?page=2
otherwise it goes to the normal page.
But I need to do this logic on another controller, which in turn is not working. See my relationships and how I'm doing:
public function grupoPerfil($slug) {
$grupo = Grupo::where('slug', $slug)->first();
$comments = Comment::whereHas('relato', function ($query) use ($grupo) {
return $query->where('grupo_id', $grupo->id);
})->paginate(10);
if($grupo){
$rels = $grupo->relatos()->with('user')->paginate(20);
return view('grupo', compact(['grupo', 'rels','comments']));
}
abort(404);
}
my blade:
#foreach($rels->sortByDesc('updated_at') as $r)
<card-relatos
url="{{localized_route('relatoUser', [$r->grupo->slug, $r->slug])}}"
getpaginate="{{ $comments->lastPage() }}"
</card-relatos>
#endforeach
But getpaginate always returns 2, as it is not related to relato_id. How do I solve this?
This is what I have done:
return Product::whereHas('category', function ($query) use ($slug) {
$query->where('slug', $slug);
})->paginate(15);

How pass Dynamic variable from url in Laravel

I need to fetch the data from database and display it view .
This is my web.php
Route::get('/businesscard/{name}', function ($name) {
//$username= App\users::where('username', $name);
$username=DB::table('users')->select('*')
->where('username', '=', $name)
// ->groupBy('status')
->get();
return view('auth.pro')->with(['username' => $username]);
return array(
'name' => $name
);
});
If the user enters domain.com/businesscard/username I need to fetch the data for the username and display it in view .It is working.But I need to remove businesscard .User need to enter domain.com/username. I have tried the below code.
Route::get('/{name}', function ($name) {
//$username= App\users::where('username', $name);
$username=DB::table('users')->select('*')
->where('username', '=', $name)
// ->groupBy('status')
->get();
return view('auth.pro')->with(['username' => $username]);
return array(
'name' => $name
);
});
If there is data it is working .but other pages are not working like login and register .Users are entering their username in registration .
The order of your route matters. See order of route declarations in laravel package
So the /{name} should be registered as the last route to avoid matching for other routes.
/{name} it means / with any value. If you try /login or /register.Then your logic is confused with this so that other pages are not working. Best way to develop as you expect like first one.
Another thing in your code there is two return second one is not doing anything. After the first one it return to view so second one unused. remove that return as well.

Laravel Route with Multiple Parameters - How to get correct database result

I am a couple of weeks in to learning Laravel and have come across a problem which I can not find the answer to by myself, or online.
I am building a directory website with urls structured like:
directory.co.uk/parks
directory.co.uk/parks/{county-name}
directory.co.uk/parks/{county-name}/{park-name}
As {park-name} is not unique, I am struggling to return the page for an individual park. The controller needs to look up the county.id using the county.slug and then the park.id using the park.county_id and the park.slug.
I have routes in the web.php file such as:
Route::get('/parks','ParksController#index')->name('parks');
Route::get('/parks/{county}/{park}','ParksController#show')->name('park');
I have Parks and Counties models and (belongsTo and hasMany relationships set up between the two).
I have this is in both models:
public function getRouteKeyName()
{
return 'seo_url';
}
Then in my ParksController, I am at a loss. I currently have:
public function show(Counties $county, Parks $park)
{
//return $park;
//dd($park);
return view('parks.park', ['park'=>$park]);
}
I have also tried the non-Eloquent way:
public function show($county_slug,$park_slug)
{
$county = DB::table('counties')->where('seo_url',$county_slug)->get();
$county_id = $county->pluck('id');
$park = DB::table('parks')->where('county_id', $county_id)->where('seo_url', $park_slug)->get();
//dd($county_id);
//return $park;
return view('parks.park', ['park'=>$park]);
}
This returns a 404 error. Any help would be much appreciated. (I have done a lot of reading on Route model binding, but can not see any examples like mine.)
Laravel has an undocumented feature in its explicit model binding, where the callback can be given the current Route the binding is for. This can allow you to access the other parameters and use them to add conditionals.
Router::bind('park', static function ($value, Route $route) {
$query = Parks::where('seo_url', '=', $value);
if ($route->hasParameter('county')) {
$county = $route->parameter('county');
$query->where('county_id', '=', $county instanceof Counties ? $county->id : $county);
}
return $query->first() ?? abort(404);
});

Trying to get a record set containing all the files of the people you follow

I'm trying to make a small function to a website that I'm creating that let's you follow other users and then your dashboard fills up with the files they upload in that order of upload date. (You can compare it to youtube. You subscribe to a channel and on the subscriptions page you see every video in order by date of people you follow).
This is my model structure (It is simplified to only show the needed values for this to work).
Follow
my_id (This is your id)
user_id (This is the id of the user that you're following)
User
id (The user id)
Files
user_id (The id of the user who uploaded the file)
path (file path)
I have tried many things now to get the data:
Follow::where('me_id', '=', Auth::user()->id)->get()->all()->files;
Follow::where('me_id', '=', Auth::user()->id)->get()->files;
The only thing that seems to work is (But this is only for 1 follow):
Follow::where('me_id', '=', Auth::user()->id)->first()->files;
It would be amazing if someone could see what I'm doing wrong.
In my Follow.php model I have it connected like this.
class Follow extends Model
{
protected $fillable = ['user_id', 'me_id'];
public function me()
{
return $this->belongsTo(User::class, 'id', 'me_id');
}
public function user()
{
return $this->belongsTo(User::class, 'id', 'user_id');
}
public function files()
{
return $this->hasManyThrough(
'App\File', //The model I'm trying to reach
'App\User', //The model I need to go through to reach the files
'id', //This is where I'm going wrong I think
'user_id', //Same here
'user_id', //Same here
'id' //Same here
);
}
}
EDIT:
I have it working doing 2 seperate database calls. But is this possible in a single call. See code underneath.
public function following(Request $request)
{
$follows = Follow::where('me_id', '=', Auth::user()->id)->get()->all();
$userIds = [];
foreach($follows as $key => $follow) {
$userIds[] = $follow->user_id;
}
$files = File::where('visible', '=', '1')->whereIn('user_id', $userIds)->orderBy('created_at', 'desc')->paginate(12)->onEachSide(3);
}
Your model definition is ok since you can get files using:
Follow::where('me_id', '=', Auth::user()->id)->first()->files;
Your mistake
The following code returns a laravel collection:
Follow::where('me_id', '=', Auth::user()->id)->get()
The following code returns an array:
Follow::where('me_id', '=', Auth::user()->id)->get()->all()
And files is a dynamic property of Follow model (Not collection nor array).
So this is not gonna work as you expect.
Your right solution
You should use eloquent relationships feature:
Follow::with('files')->where('me_id', '=', Auth::user()->id)->get()
This returns a collection of Follow containing all their respective files. like:
[
'my_id' -> 1,
'user_id' -> 1,
'files' -> [
'user_id' -> 1,
'path' -> '/foo/bar'
]
]
I think you could do this in two steps.
Get the user that the user is following
Get the files from users with ids from the first query

Nested Eager loading relationships in Laravel

I am creating a forum software using Laravel and I'm trying to access the most recent posts made within a specific topic using latestPost as defined in my model below
public function latestPost() {
return $this->hasOne('App\Post')->with('thread')->with('author')->latest();
}
Here is how the nested relationships are defined in App\Post.php
public function author()
{
return $this->belongsTo('App\User', 'author_id');
}
public function thread()
{
return $this->belongsTo('App\Thread', 'thread_id');
}
public function topic() {
return $this->belongsTo('App\Topic');
}
I have been able to access posts of threads, authors etc no problem, and when I have {{ $topic->latestPost }} in my views, it will list the object including relationships successfully. But as soon as I try to display a specific part such as {{ $topic->latestPost->author->username }} I am getting the following error: Trying to get property of non-object
In this specific view, topics is yet another relationship pulled from Categories like so in the Controller and getting $topics using a #foreach on $categories->topics:
public function index() {
$categories = Category::orderBy('order', 'asc')->get();
return view('welcome', compact('categories'));
}
Here is a dump of $categories: http://dumptext.com/H8Nq16ea
Maybe you want to use nested eager loading.
Change: return $this->hasOne('App\Post')->with('thread')->with('author')->latest();
To this: return $this->hasOne('App\Post')->with('thread.author')->latest();
Also i never heard about latest() and the end of your return statement. Maybe you can try it with orderBy as shown below.
`return $this->hasOne('App\Post')->with('thread.author')->orderBy('id')->first;`
I guess you can use the orderBy('id')->reverse() function if the result is not in the order you want. Let me know if it helped you out.
You should make sure you have author for latest post you want to display. Otherwise if you expect not to have one for each record, you should try:
{{ $topic->latestPost->author ? $topic->latestPost->author->username : 'No author' }}
In addition instead of:
return $this->hasOne('App\Post')->with('thread')->with('author')->latest();
you can use
return $this->hasOne('App\Post')->with('thread','author')->latest();

Resources