Show information about several tables on the same view on Laravel - php

I'm trying to show a list of question and his respective answers. I store all on 3 different database tables, questions>type of answer>list of possible answers.
This is what I've done on the controller:
public function show()
{
$questions = DB::table('questions')
->join('typeAnswers', 'typeAnswers.id', '=', 'questions.answer_id')
->join('answers', 'answers.typeAnswers_id', '=', 'typeAnswers.id')
->get();
return view('questions.showquestions', ['questions' => $questions]);
}
On the view I use a foreach iteration to show all the questions:
#extends('welcome')
#section('content')
#foreach($questions as $question)
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{$question->statement}}</h3>
</div>
<div class="panel-body">
{{$question->value}}
</div>
</div>
#endforeach
#endsection
On the database for testing I just have one question, and the possible answers are Yes or No. But instead of see one question and two possible answers, I get the same question 2 times and each time a one different answer.

Check this query:
$questions = DB::table('questions')
->join('typeAnswers', 'typeAnswers.id', '=', 'questions.answer_id')
->join('answers', 'answers.typeAnswers_id', '=', 'typeAnswers.id')
->get();
You are joining questions table with typeAnswers so the result here is some thing like:
Q1 A1
Q1 A2
And on view the required result is like:
Q1 [A1, A2]
So that you can show answers under one question. Modify your query accordingly.

Related

How to log through in Blade view array of nested collection in laravel

I am using groupBy and getting this result in controller
$this->savedTimers = TimeLog::where('id',23)
->join('projects', 'projects.id', '=', time_logs.project_id')
->select('projects.project_name', 'time_logs.*')
->orderByDesc('created_at')
->get();
$this->savedTimers = $savedData->groupBy('project_id')->all();
and when i tried to loop through in blade like this
#forelse($savedTimers as $key=>$groupTimer)
#foreach($groupTimer as $timer)
<div class="row">
<div class="card card-fluid">
<h2>
Group
</h2>
</div>
</div>
#endforeach
#empty
<div class="card card-fluid"><h2>No Record</h2></div>
#endforelse
getting this error
Property [created_at] does not exist on this collection instance.
can somebody helpe me to get out of this
First check your table in database and see that created_at column exists or not.
And at the same time check your model also, that your public $timestamps = false or not. Because if it is false or commented then created_at and updated_at columns will not be created in table.
If all goes well.
Check:->orderBy('created_at','desc')
$this->savedTimers = TimeLog::where('id',23)
->join('projects', 'projects.id', '=', time_logs.project_id')
->select('projects.project_name', 'time_logs.*')
->orderBy('created_at','desc')
->get();
$this->savedTimers = $savedData->groupBy('project_id')->all();

Issue in fetching data from db to the views in laravel 5.2

Im new to laravel and studying it by creating some test projects myself in laravel 5.2. But i got stuck now with some issue in fetching data correctly from db in laravel 5.2 and display the result. I have a menu table in my db with fields -> id, menutype, itemname, itemprice, itemimage with some datas in it. I want to display it on my webpage in a specific way like as seen on the below given screenshot.
See:
And this one is my db table screenshot with the values on it. See:
i added the below codes in my Controller (GuestController.php)
public function menu() {
$result=DB::table('menu')->select('menutype')->distinct()->get();
return view('guest.menu')->with('data',$result);
}
and in the View (menu.blade.php), i had given the below code:
<div class="row">
#foreach($data as $row)
<div class="col-1-3">
<div class="wrap-col">
<h3>{{$row->menutype}}</h3>
<?php
$item=DB::table('menu')->where('menutype', $row->menutype)->get();
?>
#foreach($item as $row)
<div class="post">
<img src="assets/images/{{$row->itemimage}}"/>
<div class="wrapper">
<h5>{{$row->itemname}}</h5>
<span>Rs.{{$row->itemprice}}/-</span>
</div>
</div>
#endforeach
</div>
</div>
#endforeach
</div>
This works perfectly and i am getting the desired output as seen on the products page screenshot given above. But i know this method is not correct, because i am giving the query statement on the View itself like as given below to fetch data and its against the MVC concept:
<?php $item=DB::table('menu')->where('menutype', $row->menutype)->get(); ?>
So is there any other simple and better way i can implement to get the above said desired output along with keeping the MVC Standards?? Please help! Thanks in advance...
Laravel's Collection can really help you out with this. Specifically, the groupBy method. First, you get all of the menu items with all the data. Then, you use the groupBy method on the Collection to group the menu items into separate arrays based on their menutype. You can then use this one Collection to do all the work in your view.
The code is shown below. You can combine a couple of the lines into one if you'd like, but it is broken out into multiple lines to show all the steps:
public function menu() {
// get all the menu items
$menuArray = DB::table('menu')->get();
// create a Laravel Collection for the items
$menuCollection = collect($menuArray);
// group the Collection on the menutype field
$groupedMenu = $menuCollection->groupBy('menutype');
/**
* Note that Eloquent queries (using Models) will automatically return
* Collections, so if you have your Menu model setup, your first two
* lines would just be:
* $menuCollection = Menu::get();
* or, all three lines could be combined into:
* $groupedMenu = Menu::get()->groupBy('menutype');
*/
// pass the grouped Collection to the view
return view('guest.menu')->with('data', $groupedMenu);
}
Now, in your view, your outer foreach will iterate through the groups. The inner foreach will iterate through the items in each group:
<div class="row">
#foreach($data as $type => $items)
<div class="col-1-3">
<div class="wrap-col">
<h3>{{$type}}</h3>
#foreach($items as $item)
<div class="post">
<img src="assets/images/{{$item->itemimage}}"/>
<div class="wrapper">
<h5>{{$item->itemname}}</h5>
<span>Rs.{{$item->itemprice}}/-</span>
</div>
</div>
#endforeach
</div>
</div>
#endforeach
</div>

Laravel displaying all posts with WHERE clause and pagenation in laravel

so i want to display post in my index page but only the posts that are reviewed by the admin. so i added another column in my database table post which is called "review" which is integer. So this is what i have in hand.
in my controller i have this
public function index()
{
$this->layout->content = View::make('partials.index',
array(
'posts' => Post::paginate(9)
));
}
and in my index page i have this
#section('content')
<div class="dashboard">
#foreach (array_chunk($posts->getCollection()->all(),2) as $row)
<div class="row">
#foreach($row as $post)
<article class="col-md-4 effect4" id="dash-box">
<p></p>
<c>{{$post->content}}</c><br>
<b>{{$post->title}}</b><br>
<d>posted..{{$post->created_at->diffForHumans()}}</d>
<hr>
</article>
#endforeach
</div>
#endforeach
<div class="page">
{{$posts->appends(Request::only('difficulty'))->links()}}
</div>
</div>
#stop
Help im newbie here i hope someone can help me out with this one hoping for a reply thanks
Just call:
Post::whereReview(1)->paginate(9);
Please read the documentation (and also the one for the query builder since these pages apply to Eloquent as well)
You can just add a where() call to the query:
$posts = Post::where('review', '=', 1)->paginate(9);
Or a shorter version (= is the default operator)
$posts = Post::where('review', 1)->paginate(9);
Or even with a dynamic method name:
$posts = Post::whereReview(1)->paginate(9);
Also you can use true instead of 1. Laravel will convert it:
$posts = Post::whereReview(true)->paginate(9);
There is also no need to do chunking that complicated:
#foreach (array_chunk($posts->getCollection()->all(),2) as $row)
You can just use the chunk method on any collection:
#foreach ($posts->chunk(2) as $row)

Laravel 4 - Too much logic in my view template?

i created a search functionality within my Laravel project - the user can search for teamnames or usernames - the result is created and returned like this:
$teams_obj = Team::where('teamname', 'LIKE', '%'.Input::get('searchterm').'%')->get();
$persons_obj = User::where('name', 'LIKE', '%'.Input::get('searchterm').'%')->orWhere('vorname', 'LIKE', '%'.Input::get('searchterm').'%')->get();
return View::make("team.search-content", array('resp' => 'resultlist', 'teams_obj' => $teams_obj, 'persons_obj' => $persons_obj))->with('user', User::find(Auth::user()->id));
Now its getting a little more complicated. I have a database table "relation" which stores if a user is a member of a team via an entry containing user_id and team_id. Laravel knows this relation.
If the search result is displayed within the view, i have to make a distinction if the current user is already a member in the respective team which is displayed in the current row. If the user is already a member within the team he should not be able to apply, otherwise he should have the option to apply.
I solved it with this:
#foreach($teams_obj as $team_obj)
<li data-teamid="{{ $team_obj->id }}">
<span>{{ $team_obj->teamname }}</span>
<?php
$data = ['user_id' => $user->id, 'team_id' => $team_obj->id];
$res = $team_obj->whereHas('Relation', function($q) use ($data) {
$q->where('team_id', '=', $data['team_id']);
$q->where('user_id', '=', $data['user_id']);
})->get();
if (count($res) == 0) {
echo'apply fct available';
}
?>
</li>
#endforeach
I fetch the relation and check if the relation of team_id and user_id is existent. But i have a strange feeling doing this within my view template. What do you think? How can i improve this?
Additionally i think it is strange that i have to make $q->where('team_id'), as I already do $team_obj-> ... but otherwise it is not working correctly.
Any help is appreciated. Thanks!
Do you have any need to show teams that your user cannot apply ? if not you can simply modify your code to get teams that your user is not a member. If you need you can do some checkup in the controller in order to get that information.
I suggest making a foreach for the every team and checking if they have relationship with the user. You can set an attribute in a team to check in the view.
Controller:
foreach($teams_obj as $team_obj){
$res = $team_obj->whereHas('Relation', function($q) use ($data) {
$q->where('team_id', '=', $data['team_id']);
$q->where('user_id', '=', $data['user_id']);
})->get();
if(count($res) == 0)
$team_obj->isApplyableByUser = true;
else
$team_obj->isApplyableByUser = false;
// You can do the same code above in one line, but it's not that compreensive
$team_obj->isApplyableByUser = count($res) == 0;
}
View:
if($team_obj->isApplyableByUser) echo'apply fct available';
Yes, too much logic for a view (in terms of best practices)
Do you have relationships set up for these? Assuming Team hasMany('User')... Why not just eager load your User models?
$teams = Team::with(['users' => function($query){
$query->where('name', 'LIKE', '%'.Input::get('searchterm').'%')
->orWhere('vorname', 'LIKE', '%'.Input::get('searchterm').'%')
}])where('teamname', 'LIKE', '%'.Input::get('searchterm').'%')
->get();
return View::make('your.view', ['teams' => $teams]);
// And in your view.
#foreach($teams as $team)
<li data-teamid="{{ $team->id }}">
<span>{{ $team->teamname }}</span>
#if(!$team->users->count())
apply fct available
#endif
</li>
#endforeach

Laravel 4 - nested results

I am new to php and larval. I have the following database tables questions and answers. Each question can have multiple answers with the corrected one indicated in the correct answer field. I am trying to list out the question with the answers following like this
this is the question....
a. first answer
b. second answer
c. third answer
d. fourth answer
I have the following code:
public static function getMultipleChoiceQuestions($chapter)
{
$data = DB::table('newQuestions')
->join('newAnswers', 'newQuestions.questionId', '=', 'newAnswers.questionId')
->where('chapterId', '=', $chapter)->orderBy('newQuestions.questionId')
->where('questionType', '=', "1")
->get();
$questions = array('questionType' => $questionType, 'data' => $data);
return $questions;
}
question table:
chapterId
questionId
questionText
answer table:
answerId
questionId
answerText
correctAnswer
The following code displays the question for each answer.
<fieldset id="group_1">
<p><div><input type="checkbox" class="checkall"> Check all</div></p>
<div style="width:600px; height:300px; overflow: auto;">
#foreach($questions['data'] as $question)
<p><input name="your_name" value="{{ $question->questionId }}" id="{{ $question->questionId }}" type="checkbox" class="questionsOnPage" />
{{ $question->questionText }}</p>
#endforeach
</div>
</fieldset>
I would like to list question then answers then next question.
Please help!
I think you need to take a further look at Eloquent. You should be able to do something like this.
Here is how you would set up the relationship. Based on this, your answers table name needs to be answers, and it needs a column named question_id. Although, you can go through the docs to learn how to set custom table names and column names.
app/models/Question.php
class Question extends Eloquent {
public function answers()
{
return $this->hasMany('Answer');
}
}
app/models/Answer.php
class Answer extends Eloquent {
public function question()
{
return $this->belongsTo('Question')
}
}
Now, once those relationships are set like that, we can really use Eloquent. You can do something like this in your view quite easily with blade.
The outer foreach will loop through each question. The the inner foreach will display each answer that belongs to that current question, then move on to the next question.
#foreach(Question::all() as $question)
<h3>{{ $question->title }}</h3>
<ul>
#foreach($question->answers->all() as $answer)
<li>{{$answer->text}}</li>
#endforeach
</ul>
#endforeach
The title and text property you see there, simply need to be the column names you have in your database. You should change those to match yours.
Using the example above, you should be able to style it how you want and place it in a form. Right now it will display the question within an h3 tag, then a unordered list with the answers below that.

Categories