Laravel 4 - nested results - php

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.

Related

Undefined property error when trying to use a relationship in Laravel

I have the following relation between a post and it's comments :
In the Post model :
public function comments()
{
return $this->hasMany('App\Comment', 'post_id');
}
In the Comment model :
public function posts()
{
return $this->belongsTo('App\Post', 'id'); // id is the primary key in posts table
}
The posts are returning without any issue in the below foreach loop, but whenever I try to use the relationship to bring the comments, I see the below error :
Foreach :
#foreach($topans as $topanswer)
<p> {{$topanswer->body}} </p>
<br>
#if(!empty($topanswer->comments))
#foreach($topans->comments as $topanscom)
<p>{{$topanscom->comment}} </p>
#endforeach
#endif
#endforeach
Error :
Undefined property: Illuminate\Database\Eloquent\Collection::$comments (View: C:\xampp\htdocs\sharp\resources\views\showPost.blade.php)
Am I missing something ?
Looks like you are trying to pull the entire collection's worth of answers in your inner foreach loop. The top level collection ($topans) is a collection of topanswers, and does not have a field comments since it is a collection.
Try to pull the second level topanswer's comments in that inner foreach loop:
#foreach($topanswer->comments as $topanscom)
Also, just as a side note, I think you've fallen into the trap of naming -- it might help to use a little bit more descriptive or different names, it would help you get out of trouble :)

GroupBy and Count - laravel

In my application, i send out surveys and group and count similar and non-similar responses. This is how my group and count is working now
NB: Take this instance as if the survey was answered by 2 clients.
Client 1 and Client 2 both selected Good for question 1
Responses
question Ans
How would you describe my services? Good (2)
How would you describe my services? Good (2)
Gender Male(1)
Gender Female(1)
How can take out the redundancy. the question repeats itself and also, when the answers repeat itself with the count.
Responses
question Name Ans
How would you describe my services? Good (2)
Gender Male(1), Female(1)
Model
public function count_answers()
{
return $this->hasMany(Answer::class)->select('answer', DB::raw('count(*) as counter'))->groupBy('answer');
}
View
#forelse ($data->questions as $item)
#foreach ($item->answers as $answer)
<tr>
<td width="30%">{{ $item->title }}</td>
<td>
#foreach ($item->count_answers as $answer)
<div>{{$answer->answer}} ({{$answer->counter}})</div>
#endforeach
</td>
</tr>
#endforeach
Controller
public function view_survey_response(Survey $data)
{
$data = Survey::where('id', $data->id)->where('user_id', Auth::user()->id)->first();
return view('answer.response', compact('data'));
};

Show information about several tables on the same view on Laravel

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.

Laravel-Displaying one to many relationship in view

I am currently adding a feature to my website that asks questions and gives multiple choice answers.
My Answer Model has code like:
protected $table = 'answer';
protected $primaryKey = 'answer_id';
protected $fillable = ['question_id'];
public function question()
{
return $this->belongsTo('App\Question','question_id')->distinct();
}
and my view is like:
#foreach ($answers as $answer)
<h2>{{$answer->question->question}}</h2>
<p>{{$answer->answer}}</p>
#endforeach
My controller is:
$answers = Answer::with('question')->first()->get();
It is displaying like:
question1
answer here
question1
answer here 2
question1
answer here 3
question2
2 answer here
question2
2 answer here 2
question2
2 answer here 3
I want to only show the question once. I am new to Laravel.
You need to flip this then, and first get your questions from the DB:
$questions = Question::with('answers')->get();
This of course assumes you've already setup a hasMany relationship in your Question model.
Then in your view you'll have two loops:
#foreach ($questions as $question)
<h2>{{$question->question}}</h2>
#foreach ($question->answers as $answer)
<p>{{$answer->answer}}</p>
#endforeach
#endforeach
Note how you first loop through questions and display the question once, then loop through the answers for each question.

getting multiple rows from db that are associated to previous selected rows. laravel 4.2 php

so here is my problem,
for a school project i have to make a quiz website in which a normal user should be able to play a quiz, so i have to show all the questions associated to the quiz and all the answers associated to the question, but when i try to do so it only shows the answers that are associated to the final question. here is my code:
// select the clicked quiz.
$quiz = Quiz::find($id);
// get all the question and answer records from db that are associated to the selected quiz.
$questions = DB::table('questions')->where('quiz_id', $id)->get();
foreach($questions as $question)
{
$answers = DB::table('answers')->where('question_id', $question->id)->get();
}
return View::make("quizzes.makeQuiz", [
"quiz" => Quiz::find($id)
])->with('quiz', $quiz)->with('questions', $questions)->with('answers', $answers);
and here is the html (using blade):
<h3>{{ $quiz->name }}</h3><br/>
#foreach($questions as $question)
<h4>{{ $question->question }}</h4>
#foreach($answers as $answer)
<p>{{ $answer->answer }}</p>
#endforeach
#endforeach
when i try to do this without a foreach i get an error that says 'Trying to get property of non-object'. i know why i get that error because obviously $questions isn't an object.
help is very much appreciated! thanks for reading!
edit*
alright so i have now changed my code to look like this:
$questions = Question::where('quiz_id', $id)->get();
foreach($questions as $question)
{
$answers = Answer::where('question_id', $question->id)->get();
}
$data = [
'quiz' => Quiz::find($id),
'questions' => $questions,
'answers' => $answers
];
return View::make("quizzes.makeQuiz", $data);
the html is basically the same, it returns the quiz and all the questions associated. but unfortunately it only returns the answers associated to the final questions while each questions has 3 answers. i think the problem lies in $answers but i don't know exactly what i am doing wrong here :( please help! thanks!
*edit
I asked this question a second time and it solved my problem, here is the link:
retrieving multiple records associated to multiple records laravel 4.2
Rewrite your return statement as such:
$data = [
'quiz' => Quiz::find($id),
'questions' => $questions,
'answers' => $answers
];
return View::make("quizzes.makeQuiz", $data);
You are currently returning an array AND trying to return chained variables. Most likely your $questions variable never reaches the view because you are passing an array first.
Plus the fact you were trying to collect the Quiz model twice for some reason is just wrong.
Also - why are you mixing Eloquent and Fluent statements to get your models? Stick to one or the other unless the situation warrants it.

Categories