At the moment I'm getting all the rows from my table, and display every category on the page. Now I want to make something new but I'm a bit stuck after trying a few things.
So now I have a link called 'photos' and when that's being clicked all the photos are being shown. Now I want to have a submenu so that I can only see the photos of a certain category. This is how a table can look like
pk imgUrl category
--------------------
1 ... portret
2 ... nature
3 ... portret
4 ... cars
When navigating to www.mysite.com/photos, then this displays all my photos regardless of the category.
Now I want to add the functionality when going to www.mysite.com/photos/portret that I only see photos from the category portret.
I was able to create the links dynamically and they go to the correct URL (www.mysite.com/photos), but the page is empty. So I don't know what is going wrong. Routing?
I'll post what I have tried and what I currently have below.
Before the navigation was static, but now that I want it dynamic I added the NavController
public function index()
{
//
//return Photo::all();
$title = "Photo";
$photos = Photo::orderBy('category')->get();
return View::make('photo')->with('title', $title)->with('photos', $photos);
//QUERY - Eloquent
//return Photo::all();
}
And it's corresponding view is nav.blade that contains this (This prints out my dynamic links)
<?php
$category = "";
?>
<ul>
#foreach($photos as $photo)
#if($category != $photo->Category)
<li> {{ $photo->Category }} </li>
<?php $category = $photo->Category; ?>
#endif
#endforeach
</ul>
Then in my route I have so I can navigate to the dynamic pages
Route::get('photos/{theme}', array('as' => '{theme}', 'uses' => 'PhotosController#show'));
Then here in my PhotosController I have
public function show($theme){
$photos = Photo::where('category', $theme);
return View::make('photo')->with('title', $theme)->with('photos', $photos);
}
And in my view photos.blade
<?php
$category = "";
?>
#foreach($photos as $photo)
{{ HTML::image("img/$photo->Link", "$photo->Title", array("class"=>"thumbnail thumbEffect")) }}
#endforeach
So I don't see or understand what I'm doing wrong. Also when going to the page www.mysite.com/photos/portret, the dynamic links don't appear anymore while this should be as it's only in the nav.blade that's being included in my template.
Can someone help me please?
EDIT: Most of my work here is due an other Q/A I found on SO and that's this Laravel Creating Dynamic Routes to controllers from Mysql database
Your code looks almost good to me, but you forgetting to get your photos from the database:
public function show($theme)
{
$photos = Photo::where('category', $theme)->get(); /// here
return View::make('photo')->with('title', $theme)->with('photos', $photos);
}
Related
I'm pretty new when it comes to Laravel & I've been trying to code this mini-account management system where I can insert accounts manually alongside their companies & salaries and delete them (pretty basic CRUD) - I'm showing these database entries in a table. Now I want to take things further by creating a button that'll re-fetch the table data and only show accounts with salary over $40,000 - and I'm kinda confused on how I approach something like this.
This is my AccountsController.php:
public function showsalary(Account $account)
{
$query = DB::table('accounts')->where('salary','>=','45000')->get();
$ordersalaries = $query;
return view ('accounts',compact('ordersalaries'));
}
Web.php:
Route::get('showsalary', 'AccountsController#showsalary')->name('accounts.showsalary');
Route::resource('/accounts','AccountsController');
And when I try to echo the rows in 'ordersalaries' variable, it says that it's not defined. Was hoping someone can show me how do I trigger the fetching on clicking a button and what am I doing wrong / missing here, thanks in advance..
in your controller
public function showsalary(Account $account)
{
$queries = DB::table('accounts')->where('salary','>=','45000')->get();
return view ('accounts',compact('queries'));
}
write this code in your view blade file.
#foreach ($queries as $query)
{{ $query->salary }}
#endforeach
I'm building a forum, and I'm trying to implement a categories page. The page is working as of now, it's dynamic so it lists all categories stored in the database. However I want to be able to click on a category and be taken to a template page. From this template page I want to pass a category ID (defined in the database as a primary key). Then all posts with the matching category ID will be displayed. I'm having trouble passing this category ID to my category page template.
Any help would be extremely appreciated!
(How categories are displayed in a list:)
#foreach($categories as $row)
<div id="newscontainer" class="container">
<?php $categoryid = $row->id; ?>
<span id='categoryname'><?= $row->categoryname ?><br></span>
<span id="categorydescription"><?= $row->categorydescription?></span>
</div>
<br>
#endforeach
Thanks!
First of all define a route in web.php:
web.php:
Route::get('category/{category}','YouController#YourCatFunction')->name('categories.list');
in your controller:
public function YourCatFunction(Category $category)
{
// here you can return view for post with that category and then display them
return $category;
}
then in your view:
#foreach($categories as $row)
<div id="newscontainer" class="container">
<span id='categoryname'>{{ $row->categoryname }}<br></span>
<span id="categorydescription">{{ $row->categorydescription }}</span>
</div>
<br>
#endforeach
You can create a web route which will handle the category calls and return the view with that category and it's posts.
First you create a route like this:
Route::get('category/{category}', 'CategoriesController#show')->name('category.show');
Then you can access this Category inside the controller and load the posts and return them like this:
public function show(Request $request, Category $category) {
return view('category.show', compact('category'));
}
Then in your view you would have something like this where you loop over available posts:
#foreach($category->posts as $post)
// do something
#endforeach
To call the route you can simply create this link:
Show
As I can see, your base namespace is ULMG, so the correct way to your Category class would be ULMG\Category
You can try this one as well.
Route web.php
Route::get('category/{categoryid}', ['as'=>'category.show','uses'=>'CategoriesController#show');
Controller CategoriesController.php
public function show($categoryid){
// some of your code.
$categoryid = DB::table('category')->select('categoryId');
return view('category.show', compact('categoryId'));
// don't forget if you have some variables and you want to view it at blade just put it inside the compact
}
View blade category.show.blade.php
#foreach($categories as $row)
<div id="newscontainer" class="container">
<span id='categoryname'>{{ $row->categoryname }}<br></span>
<span id="categorydescription">{{ $row->categorydescription }}</span>
</div>
#endforeach
For anyone else who is having the same issue:
(I had a eureka moment...)
My forums.blade.php file (where the user selects the category they want to view:
Here, it's calling the category route (which is where the posts will be displayed) then it's setting the category ID in one url. It will look like this in the browser: www.example.test/category/(ID) (so when I query the database for posts under that category it will extract them).
<span id='categoryname'><?= $row->categoryname ?><br></span>
My web.php file:
I basically grabbed the id from the URL which was passed through when the user clicked on the link.
Route::get('/category/{id}', 'CategoriesController#getid');
My CategoriesController.php file:
Here I have defined a function, so in the web.php it knows to go to the function with the attribute of getid. Once it has found the correct function it sets the $catid the same value as $id. Then it returns to the categorytemplate view (which is the template requiring the ID in the first place to display the posts) with the $catid variable in a compact function.
public function getid($id){
$catid = $id;
return view('categorytemplate', compact('catid'));
}
I hope my explanation is clear enough to understand. And I hope this can help someone else with this issue in the future!
Thanks again to everyone else suggesting ideas.
I have set up two model with its row in table. And made a single form to fill both tables and it works perfectly
Tour.php
public function featuredImage()
{
return $this->hasOne('App\FeaturedImage');
}
tours table
id|name|content|featured_status
featuredImage.php
public function tour()
{
return $this->belongsTo('App\Tour');
}
Featured_images table
id|tour_id|path|name
Code in my controller to pass data to view.
$tours = Tour::where('featured', 1)->get();
return view('public.pages.index')
->withTours($tours);
Code in my view
#foreach($tours as $featured)
<div class="thumbnail">
<img src="{{$featured->featuredimage->path}}" alt="{{$featured->featuredImage->name}}">
</div>
<h4>{{$featured-name}}</h4>
#endforeach
The trouble is I'm not able to fetch featured images by writing
{{$featured->featuredimage->path}}
and the error is
Trying to get property of non-object
on the line {{$featured->featuredimage->path}}. I have used this method in my previous project and it had worked perfectly but it isn't going well in this one.
I tried replacing {{$featured->featuredimage->path}} with {{$featured->featuredImage->path}} but didn't worrked out.
Do this:
{{ $featured->featuredImage()->path }}
Also, you're creating a lot of additional queries here. You should use eager loading to solve N + 1 problem:
$tours = Tour::with('featuredImage')->where('featured', 1)->get();
And display data with:
{{ $featured->featuredImage->path }}
This is what I want to do:
Display a checkbox for the tvshow field entry(from the tvshow table) only if that field entry doesn't match the entries for a given user id in the 'watchedtvshow' table
Table structure for 'tvshow':
id tvshow
Table structure for 'watchedtvshow'
id uid tvid(id of the tvshow)
Here is my controller method:
$tvshow = TVShow::with('watchedtvshow')->get();
return View::make('browse',['tvshow' => $tvshow]);
My View:
#foreach($tvshow as $show)
{{ $show->title }} {{ 'a checkbox' }}
#endforeach
What I tried:
In my controller method:
$tvshow = TVShow::with('watchedtvshow')->get();
$uid = NULL;
if(Auth::check())
$uid = Auth::user()->id;
return View::make('browse',[
'tvshow' => $tvshow,
'uid' => $uid,
]);
In my view:
#foreach($tvshow as $show)
{{ $show->title }}
#foreach($show->watchedtvshow as $watchedtvshow)
#if($watchedtvshow->uid == $uid)
{{'don't show checkbox'}}
#else
{{'show checkbox'}}
#endif
#endforeach
#endforeach
The problem:
The thing is the second foreach loop executes only for the times it finds a watched tv show, otherwise it doesn't. So it just won't show any checkboxes.
I'm not an experienced coder, haven't really encountered anything like this before, I've spent three whole days trying to solve this, using count, for loops and what not, but I can't. Does anybody know how to achieve this?
First off a quick pointer: you can get the logged-in user's ID with Auth::id() rather than having to set it to null, then check if they're logged in then get the id directly off the model.
As for your problem, you're quite right that using the code you have you won't be getting the full story. What you need to do is get a list of all TV shows (regardless of user having it) and additionally a list of all TV shows the user has seen. Now, you can do this many ways, but the best 'Laravel way' is to model the relationship between User and TVShow. Your code doesn't mention this so I won't assume you have already done it. Your database is, of course, already set up for this so all you need to do is create the relationship. In this case, the relationship you need is a belongsToMany (a user can 'have' (have watched) many shows, and a show can 'have' (have been watched by) many users:
// in User.php
public function shows()
{
return $this->belongsToMany('TVShow', 'watchedtvshow', 'uid', 'tvid');
}
// in TVShow.php
public function users()
{
return $this->belongsToMany('User', 'watchedtvshow', 'tvid', 'uid');
}
Once you have this you can get a list of all users that have watched a show with:
$show->users;
Or you can get a list of all shows a user has watched with:
$user->shows;
Now putting that all together you should use Laravel's collections to detect whether a given item if in both arrays:
// in the controller:
$shows = TVShow::all();
if (Auth::check()) {
$watched = Auth::user()->shows;
} else {
// just create an empty collection so we can assume a consistent API
$watched = new \Illuminate\Support\Collection;
}
return View::make('browse', compact('shows', 'watched'));
// in browse.blade.php
#foreach($shows as $show)
{{ $show->title }}
#if ($watched->contains($show)
<span class="glyphicon glyphicon-ok"></span>
#else
<span class="glyphicon glyphicon-remove"></span>
#endif
#endforeach
Something like that?
I am using Paris (which is built on top of Idiorm).
I have the following Model classes (example inspired from the documentation on github):
<?php
class Post extends Model {
public function user() {
return $this->belongs_to('User');
}
}
class User extends Model {
public function posts() {
return $this->has_many('Post'); // Note we use the model name literally - not a pluralised version
}
}
So now I can do the following (works well):
// Select a particular user from the database
$user = Model::factory('User')->find_one($user_id);
// Find the posts associated with the user
$posts = $user->posts()->find_many();
// Select a particular post from the database
$post = Model::factory('Post')->find_one($post_id);
// Find the user associated with the post
$user = $post->user()->find_one();
But I'd like to do the following aswell:
$posts = Model::factory('Post')->find_many();
foreach ($posts as $post) {
echo($post->user()->find_one()->username); // generates a query each iteration
}
Unfortunately this creates a query for each iteration. Is there a way to tell Paris or Idiorm to take the associated information in the first find_many query ?
How are you supposed to retrieve information with Paris to minimize the numbers of query ? I'd like not to have to manually specify the join condition (this is the reason why I am using Paris and not Idiorm)
I am the current maintainer of the Paris and Idiorm projects. Unfortunately what you describe here is a case for a custom query and not something that Paris was ever built to solve. The philosophy of Paris and Idiorm is to stick as close to the 80/20 principle as possible and your use case is in the 20.
It would be interesting to know how you ended up solving this problem.
I've had exactly the same problem, and ended up with this (a bit ugly) solution:
$posts = Model::factory('Post')...->limit($perpage)->find_many();
$user_ids = $user_lookup = array();
foreach($posts as $post) $user_ids[] = $post->user_id;
$users = Model::factory('User')->where_id_in($user_ids)->find_many();
foreach($users as $user) $user_lookup[$user->id] = $user;
Only 2 selects. And later in template:
{% for post in posts %}
<h2>{{ post.title }}</h2>
by author: {{ user_lookup[post.user_id].username }}
{% endfor %}
But it only works if you don't have hundreds of posts showing on one page.