Can't save quiz answers - php

I'm trying to build quiz system and i'm stuck on this.
public function store(Quizze $quizzes)
{
$data = request()->validate([
'title.title' => 'required',
'questions.*.question' => 'required',
'answers.*.answer' => 'required',
], [
'title.title.required' => 'გთხოვთ, შეიყვანოთ ქვიზის სახელი.',
'questions.*.question.required' => 'გთხოვთ, შეიყვანოთ შეკითხვა.',
'answers.*.answer.required' => 'გთხოვთ, შეიყვანოთ პასუხი.'
]);
$storeQuiz = $quizzes->create($data['title']);
$storeQuiz->questions()->createMany($data['questions']);
$storeQuiz->questions()->answers()->createMany($data['answers']);
return redirect('admin/quizzes');
}
It's saving quiz title and quiz question but it's errors on questions it don't like
$storeQuiz->questions()->answers()->createMany($data['answers']);
It's errors Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::answers()
Quiz Model relation:
public function questions() {
return $this->hasMany(QuizQuestion::class, 'quizze_id', 'id');
}
Question Model relation :
public function answers() {
return $this->hasMany(QuizAnswer::class, 'question_id', 'id');
}

$storeQuiz->questions()->answers()->createMany($data['answers']);
answers() does not recognize the question. You can try this :
$storeQuiz = $quizzes->create($data['title']);
foreach($data['questions'] as $q){
$question = $storeQuiz->questions()->create($q);
$question->answers()->createMany($data['answers']);
}

Related

Array to string conversion (laravel 7)

I want to make a quiz app in Laravel and I've got some error: array to string conversion
This is my controller:
public function validateForm1($request)
{
return $this->validate($request, [
'quiz_id' => 'required',
'question' => 'required',
'options' => 'required|array',
'options.*' => 'required|string',
'correct_answer' => 'required',
]);
}
public function buat(Request $request)
{
$data = $this->validateForm1($request);
$question = (new Pertanyaan)->storeQuestion($data);
$Answer = (new Jawaban)->storeAnswer($data,$question);
return redirect()->back()->with('message','Pertanyaan berhasil disimpan');
}
This is my question model:
public function storeQuestion($data)
{
return Pertanyaan::create($data);
}
This is my answer model:
public function storeAnswer($data, $question)
{
foreach ($data['options'] as $key => $option) {
$is_correct = false;
if ($key == $data['correct_answer']) {
$is_correct = true;
}
$answer = Jawaban::create([
'question_id' => $question->id,
'answer' => $option,
'is_correct' => $is_correct,
]);
}
}
You have to use like this
return $this->validate($request, [
'quiz_id' => 'required',
'question' => 'required',
'options' => 'required|array',
'correct_answer' => 'required',
]);
Then your error remove automatically array to string conversion
this error i got when i use guarded in model, so i change it to fillable and it work properly.
sorry if im not capturing all of my model.
after read the documentation about special variable eloquent, i lil understand.
here the link i read but in indonesian leanguage. and sorry for my bad english sir. im new here
https://id-laravel.com/post/mengenal-eloquent-variable-spesial/
When I had this error, it was caused by an error in my Model. I had the table name formatted as an array, like protected $table = ['log'];. Correcting this to protected $table = 'log'; fixed the problem.

LogicException in Model.php line 2709: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

I'm supposed to display author details in bookformat method. But facing LogicException. Any suggestions thanks in advance. Im getting error like this LogicException in Model.php line 2709: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation. Any help that would be great for me. If I comment authors in bookFormat() everything works fine. But Idk why I'm unable to get author details in my bookformat().
#booksController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use App\Models\Book;
use App\Models\Author;
class BooksController extends Controller
{
public function index()
{
$books = Book::all();
$results = [];
foreach ($books as $book) {
$results [] = $this->bookFormat($book);
}
return $results;
}
public function bookFormat($book){
return [
'Id' => $book->id,
'Title' => $book->title,
'Author' => [
'Id' => $book->author->id,
'First_name' => $book->author->first_name,
'Last_name' => $book->author->last_name
],
'Price' => $book->price,
'ISBN' => $book->isbn,
'Language' => $book->language,
'Year' => $book->year_of_publisher
];
}
}
//book.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
public $timestamps = TRUE;
protected $table = 'books';
//rules
public static $rules = [
'title' => 'required|max:255',
'isbn' => 'required|max:50',
'author_id' => 'required|max:255',
'language' => 'required|max:255',
'price' => 'required|max:255',
'year_of_publisher' => 'required'
];
//relationship
public function author() {
$this->belongsTo(Author::class);
}
}
Instead of:
public function author() {
$this->belongsTo(Author::class);
}
you should have:
public function author() {
return $this->belongsTo(Author::class);
}
Notice the return difference.

Laravel call to member function create() on a non-object

I'm trying to seed a database using some model factories but I'm getting error call to member function create() on a non-object
Below are my model factories:
$factory->define(App\Organisation::class, function ($faker) {
return [
'name' => $faker->company,
];
});
$factory->define(App\Department::class, function ($faker) {
return [
'name' => $faker->catchPhrase,
'organisation_id' => factory(App\Organisation::class)->make()->id,
];
});
$factory->define(App\User::class, function ($faker) {
return [
'email' => $faker->email,
'password' => str_random(10),
'organisation_id' => factory(App\Organisation::class)->make()->id,
'remember_token' => str_random(10),
];
});
In my seeder I'm using the following to create 2 organizations and a associate a user and a department to each organization and then to make a user the manager of that department:
factory(App\Organisation::class, 2)
->create()
->each(function ($o)
{
$user = $o->users()->save(factory(App\User::class)->make());
$department = $o->departments()->save(factory(App\Department::class)->make());
$department->managedDepartment()->create([
'organisation_id' => $o->id,
'manager_id' => $user->id,
]);
});
However I'm getting fatalerrorexception call to member function create() on a non-object
I thought $department is an object?
My department model is as follows:
class Department extends Model
{
protected $fillable = ['name','organisation_id'];
public function organisation()
{
return $this->belongsTo('App\Organisation');
}
/* a department is managed by a user */
public function managedDepartment()
{
$this->hasOne('App\ManagedDepartment');
}
}
And my managedDepartment model is as follows:
class ManagedDepartment extends Model
{
protected $table = 'managed_departments';
protected $fillable = ['organisation_id', 'department_id', 'manager_id',];
public function department()
{
$this->belongsTo('App\Department');
}
public function manager()
{
return $this->belongsTo('App\User');
}
}
Can anyone help?
Try to return your relation
public function department()
{
return $this->belongsTo('App\Department');
}
And here
/* a department is managed by a user */
public function managedDepartment()
{
return $this->hasOne('App\ManagedDepartment');
}
I think it will resolve your problem.
Firstly, do not make foreign keys fillable!
Secondly, where is your organisation function in ManagedDepartment? You should create one, otherwise the following will not work, because association is not possible.
Thirdly, I think you should change make() to create() in the following
$factory->define(App\Organisation::class, function ($faker) {
return [
'name' => $faker->company,
];
});
$factory->define(App\Department::class, function ($faker) {
return [
'name' => $faker->catchPhrase,
'organisation_id' => factory(App\Organisation::class)->create()->id,
];
});
$factory->define(App\User::class, function ($faker) {
return [
'email' => $faker->email,
'password' => str_random(10),
'organisation_id' => factory(App\Organisation::class)->create()->id,
'remember_token' => str_random(10),
];
});
Furthermore:
factory(App\Organisation::class, 2)
->create()
->each(function ($o)
{
$user = factory(App\User::class)->create();
$o->users()->attach($user->id);
$department = factory(App\Department::class)->create();
$o->departments()->attach($department);
$managedDep = new ManagedDepartment();
$managedDep->associate($o);
$managedDep->associate($user);
$managedDep->associate($department);
$managedDep->save();
});

PHP, Yii2 GridView filtering on relational value

Following on from this:
Yii2 how does search() in SearchModel work?
I would like to be able to filter a GridView column of relational data. This is what I mean:
I have two tables, TableA and TableB. Both have corresponding models generated using Gii. TableA has a foreign key to a value in TableB, like this:
TableA
attrA1, attrA2, attrA3, TableB.attrB1
TableB
attrB1, attrB2, attrB3
attrA1 and attrB1 are the primary keys of their corresponding tables.
Now, I have a Yii2 GridView of attrA2, attrA3 and attrB2. I have a working filter on attrA2 and attrA3 so that I can search on column values. I also have a working sort for these two columns too - by just clicking on the column header. I would like to be able to add this filtering and sorting on attrB2 too.
My TableASearch model looks like this:
public function search($params){
$query = TableA::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$this->addCondition($query, 'attrA2');
$this->addCondition($query, 'attrA2', true);
$this->addCondition($query, 'attrA3');
$this->addCondition($query, 'attrA3', true);
return $dataProvider;
}
In my TableA model, I set the related value like this
public $relationalValue;
public function afterFind(){
$b = TableB::find(['attrB1' => $this->attrB1]);
$this->relationalValue = $b->relationalValue;
}
Although it is probably not the best way of doing this. I think I have to use $relationalValue somewhere in my search function but I'm not sure how. Similarly, I would like to be able to sort by this column too - just like I can for attrA2 and AttrA3 by clicking on the header link`. Any help would be appreciated. Thanks.
This is based on the description in the guide. The base code for the SearchModel comes from the Gii code generator. This is also assuming that $this->TableB has been setup using hasOne() or hasMany() relation. See this doc.
1. Setup search model
In TableASearch model add:
public function attributes()
{
// add related fields to searchable attributes
return array_merge(parent::attributes(), ['TableB.attrB1']);
}
public function rules()
{
return [
/* your other rules */
[['TableB.attrB1'], 'safe']
];
}
Then in TableASearch->search() add (before $this->load()):
$dataProvider->sort->attributes['TableB.attrB1'] = [
'asc' => ['TableB.attrB1' => SORT_ASC],
'desc' => ['TableB.attrB1' => SORT_DESC],
];
$query->joinWith(['TableB']);
Then the actual search of your data (below $this->load()):
$query->andFilterWhere([
'like',
'TableB.attrB1',
$this->getAttribute('TableB.attrB1')
]);
2. Configure GridView
Add to your view:
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
/* Other columns */
'TableB1.attrB1',
/* Other columns */
]
]);
Filtering a gridview by a column is damn easy in Yii 2.0. Please add the filter attribute to a gridview column having lookup values, as under:
[
"class" => yii\grid\DataColumn::className(),
"attribute" => "status_id",
'filter' => ArrayHelper::map(Status::find()->orderBy('name')->asArray()->all(), 'id', 'name'),
"value" => function($model){
if ($rel = $model->getStatus()->one()) {
return yii\helpers\Html::a($rel->name,["crud/status/view", 'id' => $rel->id,],["data-pjax"=>0]);
} else {
return '';
}
},
"format" => "raw",
],
I'm stuck with this problem too, and my solution is rather different. I have two simple models:
Book:
class Book extends ActiveRecord
{
....
public static function tableName()
{
return 'books';
}
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author_id']);
}
And Author:
class Author extends ActiveRecord
{
public static function tableName()
{
return 'authors';
}
public function getBooks()
{
return $this->hasMany(Book::className(), ['author_id' => 'id']);
}
But my search logic is in different model. And i didn't find how can i implement search without creating additional field author_first_name. So this is my solution:
class BookSearch extends Model
{
public $id;
public $title;
public $author_first_name;
public function rules()
{
return [
[['id', 'author_id'], 'integer'],
[['title', 'author_first_name'], 'safe'],
];
}
public function search($params)
{
$query = Book::find()->joinWith(['author' => function($query) { $query->from(['author' => 'authors']);}]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => array('pageSize' => 50),
'sort'=>[
'attributes'=>[
'author_first_name'=>[
'asc' => ['author.first_name' => SORT_ASC],
'desc' => ['author.first_name' => SORT_DESC],
]
]
]
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
....
$query->andWhere(['like', 'author.first_name', $this->author_first_name]);
return $dataProvider;
}
}
This is for creating table alias: function($query) { $query->from(['author' => 'authors']);}
And GridView code is:
<?php echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'id',
'filter' => false,
],
[
'attribute' => 'title',
],
[
'attribute' => 'author_first_name',
'value' => function ($model) {
if ($model->author) {
$model->author->getFullName();
} else {
return '';
}
},
'filter' => true,
],
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
I will appreciate any critiques and advice.

Call to undefined method Illuminate\Database\Query\Builder::associate()

Reference: How can I update an existing Eloquent relationship in Laravel 4?
$userinfo = \Userinfo::find($id);
\User::find($id)->userinfo()->associate($userinfo)->save();
I'm getting the error: Call to undefined method Illuminate\Database\Query\Builder::associate()
Here is the entire method:
public function saveUser($id)
{
$user = \User::find($id);
$userdata = \Input::all();
$rules = array(
'email' => 'required|email',
'state' => 'size:2',
'zip' => 'size:5',
'phone' => array('regex:/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/')
);
$validator = \Validator::make($userdata, $rules);
if ($validator->passes())
{
if ($userdata['email'] !== $user->email)
{
$rules = array('email' => 'unique:users');
$validator = \Validator::make($userdata, $rules);
if ($validator->fails()) return Redirect::route('admin.user.edit', array('user' => $user))
->with('error', 'Specified email already exists.');
}
$user->email = $userdata['email'];
$user->firstname = $userdata['firstname'];
$user->lastname = $userdata['lastname'];
$userinfoArray = array(
'address' => $userdata['address'],
'city' => $userdata['city'],
'state' => $userdata['state'],
'zip' => $userdata['zip'],
'phone' => preg_replace('/[^0-9]/', '', $userdata['phone'])
);
$user->save();
if (!$user->userinfo)
{
$userinfo = new \Userinfo($userinfoArray);
$userinfo = $user->userinfo()->save($userinfo);
}
else
{
$userinfo = \Userinfo::find($id);
\User::find($id)->userinfo()->associate($userinfo)->save();
//$user->userinfo()->update($userinfoArray);
}
return \Redirect::route('admin.user.detail', array('id' => $id))
->with('success', 'User updated.');
}
return \Redirect::route('admin.user.edit', array('id' => $id))
->withInput()
->withErrors($validator);
}
associate() is a method of the belongsTo relationship, but it looks like from the above you are trying to call it via the hasOne relationship.
I am just guessing as you have not provided your eloquent model class code so can't see how you have set the relationships exactly, but if you have:
class User extends Eloquent {
public function userinfo()
{
return $this->hasOne('Userinfo');
}
}
class Userinfo extends Eloquent {
public function user() {
return $this->belongsTo('User');
}
}
Then associate needs to be called against Userinfo as this has the belongsTo relationship to which the associate() method is attached.
For example
$user = \User::find(4);
$userinfo = \UserInfo::find(1);
$userinfo->user()->associate($user);
$userinfo->save();
Will set the foreign key user_id in the user_info table to the id of the $user object.
Looking at your above code it doesn't appear that this is what you are actually trying to do and that the
$user->userinfo()->update($userinfoArray);
call which you have commented out will in fact do what you seem to be trying to achieve, which is to update the userinfo that is related to the current user if that user already exists.
Hope this helps.
Glen
Change hasOne to belongsTo. It will look like:
class User extends Eloquent {
public function userinfo()
{
return $this->belongsTo('Userinfo');
}
}
class Userinfo extends Eloquent {
public function user() {
return $this->belongsTo('User');
}
}
I was stuck on this problem for a few days and it ended up being quite simple to solve. I had created a folder called 'models' in my 'app' folder but I had forgotten to reconfigure my auth.php file.
This was my error.
Call to undefined method Illuminate\Database\Query\Builder
I fixed it by opening the auth.php in the config folder and changing the following line to include my models folder.
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => Foodie\User::class,
fix:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => Foodie\Models\User::class,
Hope this helps!
You need to specify the field related like this:
public function profile()
{
return $this->hasOne('App\AdmProfile', 'id');
}

Categories