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.
Related
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'));
};
I have relations like this
User->hasMany->reviews
Review->belongsTo->user
Review->hasMany->ReviewAnswer
ReviewAnswer->belongsTo->Review
Now I try to display answers for specific review. My reviewAnswer table looks like:
Id, review ID, text
But the problem is when I do that:
#foreach($user->reviews as $data)
#foreach($data->reviewAnswers->where('review_id', $data->id) as $answer)
{{$answer->text}}
#endforeach
#endforeach
Then reviews displays okay, but I get the same answers for every review. How to repair that?
Make sure to check if all the relationships are correct. In this example, I assume that your models are stored in your app folder.
First, your User model should have reviews
public function reviews() {
return $this->hasMany("App\Review", "user_id", "id");
}
Next, set up your Review model to have answers
public function answers() {
return $this->hasMany("App\ReviewAnswer", "review_id", "id");
}
Then this is how you'll get all users with their respective reviews and answers
$users = User::with("reviews.answers")->get();
Finally, peform the loop in your view
#foreach($users as $user)
#foreach($user->reviews as $review)
#foreach($review->answers as $answer)
#endforeach
#endforeach
#endforeach
Try using the hasManyThrough() option which the eloquent models provide you.
Link: Laravel Eloquent Relations
This means in your case you would add:
class User extends Model {
public function reviewAnswers(
return $this->hasManyThrough(ReviewAnswer::class,Review::class);
)
}
and then simply access it in blade as:
#foreach($user->reviewAnswers() as $reviewAnswer) {
{{$reviewAnswer->text}}
}
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.
I have two tables
One QUESTIONS_TITLES entry has many QUESTIONS entries. The titles contain a group of questions.
QUESTIONS
id | question | ... | question_titles_id
QUESTIONS_TITLES
id | title
MODEL QUESTION
class Question extends \Eloquent {
public function questionTitle() {
return $this->belongsTo('QuestionsTitle', 'question_titles_id');
}
}
MODEL QUESTION
class QuestionsTitle extends \Eloquent {
protected $fillable = ['title', 'question_cat_id', 'type'];
protected $table = 'questions_titles';
public function question() {
return $this->hasMany('Question');
}
}
in my question controller i do:
$questions = Question::all();
$this->layout->content = View::make('questions.index', compact('questions'));
in my view i want a group of questions with the corresponding parent title
#foreach ($questions as $question)
<tr>
<td>{{ $question->questionTitle()->first()->title }}</td>
<td>{{ $question->id }}</td>
<td>{{ $question->question }}</td>
</tr>
#endforeach
this works. but why do i need first()? it doesn't look clean
when i drop it i get
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$title (View: /vagrant/app/views/questions/index.blade.php)
$question->questionTitle() returns a BelongsTo object, not the QuestionTitle object. When you call $question->questionTitle()->first() you're executing the first() method on the relationship. This through laravel magic is getting you the correct answer. Though what you should really be doing is: $question->questionTitle->title. When you access the questionTitle attribute Laravel automatically resolves the relationship for you.
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.