I am getting an error when trying to save my eloquent model as follows:
Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an instance of Illuminate\Database\Eloquent\Model, string given,
I have a model Question
it hasMany AnswerOption
on the other side AnswerOption belongsTo Question
I have a model QuestionRevision
it hasMany QuestionRevisionAnswerOption
on the other side QuestionRevisionAnswerOption belongsto QuestionRevision
Basically I want to copy the AnswerOptions from a Question I have retrieved to a new instance of QuestionRevision (as QuestionRevisionAnswerOptions).
I have saved a new QuestionRevision ($origRev) successfully. Now I am trying to add the QuestionRevisionAnswerOptions that go with it. This is where I get the error Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an instance of Illuminate\Database\Eloquent\Model, string given,
I have tried saving the QuestionRevisionAnswerOptions all at once as an array using saveMany and also individually but I get the same error either way.
Here is the relevant code:
$original = Question::findOrFail($qId); // find the original question
$origRev = new QuestionRevision();
// copy some stuff from original to origRev
$origRev->save(); // works to here
// now get the answerOptions from original and copy to $origRev
foreach ($original->answerOptions as $ao)
{
$answerOption = new QuestionRevisionAnswerOption(['answer_text'=> $ao->answer_text,
'answer_explanation' => $ao->answer_explanation,
'answer_option_id' => $ao->id,
'is_correct' => $ao->is_correct
]);
$origRev->revisionAnswerOptions()->save($answerOption); //This is the line that generates the error.
}
Why am I getting this error and how can I correct it?
Related
I understand Laravel is checking the object reference id to check if the object existed, so the save() method will run the edit method to edit it. and if it's a new object, it will run the create() method.
but I can't find the codes behind it, in the Eloquent package.
I want the exact address of the file that includes these codes
from the blow codes I infer the above conclusion:
I wrote this code in Laravel:
$setting = new Setting;
$setting->name = 'name1';
$setting->save();
$setting->name = 'name2';
$setting->save();
after executing I see just name2 in the database and it seems, after saving name1 Laravel edit that and save name2 in the database.
and after I execute this code:
$setting = new Setting;
$setting->name = 'name1';
$setting->save();
$setting = new Setting;
$setting->name = 'name2';
$setting->save();
and I saw both the records saved correctly, so I have name1 and name2.
You can find the code for Eloquent's save() method in vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 833 in Laravel 8.12.
The behaviour that you're observing is a characteristic of the Active Record pattern, which Laravel is based on. Each time you use new to create an Eloquent model, it's creating a object that will represent a row in your database. Within Eloquent's save() method, it will check to see if a record already exists, and if it does it will update it (code below).
if ($this->exists) {
$saved = $this->isDirty() ?
$this->performUpdate($query) : true;
}
Your code is working as expected.
I am working on a project where I need to update two related models in my controller. Below, I am creating one transaction record for a user that can have many transactions. After that, I need access to the id of the recently created transaction, but since thats hasMany relationship, laravel is throwing an error.
UserModel
public function transaction()
{
return $this->hasMany('App\Model\Transaction');
}
Controller
$user->transaction()->create([
...
...
])->save();
$devUnit = new DevUnit();
$devUnit->transaction_id = $user->transaction()->id; //this throws an error
Error
Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$id
Sorry, totally misread your question.
Save the result of the create method to a variable to get access to the populated model with the ID.
$transaction = $user->transaction()->create([
//
]);
$timeshareUnit = new TimeshareUnit();
$timeshareUnit->transaction_id = $transaction->id;
I'm trying to retrieve data from two tables and in order using a hasMany relationship. i.e
Public childModel (){
return $this->hasMany(childModel);
}
In the view when I run the foreach loop:
foreach($parentModel as $parentModel)
or
foreach($parentModel->childModel as $childModel)
then
{{parentModel->childModel}}
I get json printed on my screen just fine (including the column I want to output.)
When I try
`{{parentModel->childModel->column}}`
I get "Trying to get property of non-object"
Figured it out. I was making a 'where' statments when i initialized the parentModel variable, that 'where' statement rejected the table in the childModel. Only found out after running tests.
I need to merge either a collection or an array (it can be either) in Laravel 5.1, but I am getting the error BadMethodCallException in Builder.php line 2071: Call to undefined method Illuminate\Database\Query\Builder::merge()
When I make a collection from scratch, I can merge to it, but I cannot merge onto the result of an Eloquent query, which I thought were collections as well. But perhaps that is not true?
Code that gives the error:
$user=User::where('user_last_name', 'Doe')->first();
$tomerge = collect(['book' => 'desk', 'foot' => 'chair']);
$newcollect = $user->merge($tomerge);
If I instead did $tomerge->merge($user) it works, but that's not what I actually need. Is there a way to use merge as I want?
To answer your question as to why it's not working...
$user = User::where('user_last_name', 'Doe')->first();
This is a single instance of a model. Not a collection. An eloquent model does not have the merge method.
If you want to append attributes to an Eloquent model, the simplest way is probably to use the $appends property and the appropriate accessor. For example, in your User model..
protected $appends = ['book', 'foot'];
public function getBookAttribute()
{
return 'desk';
}
public function getFootAttribute()
{
return 'chair';
}
However, note that this will affect every instance of your User model.
I'm trying to get my route to insert a new row into the database, and if successful return the record (with its new primary key id) in some JSON. I'm getting the following error:
{
"error":
{
"type":"BadMethodCallException",
"message":"Call to undefined method Illuminate\\Database\\Query\\Builder::to_array()",
"file":"\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Query\\Builder.php",
"line":1418
}
}
This is my route:
Route::post('/client/create', function()
{
$client = Client::create(Input::all());
if($client)
{
return json_encode(array('Result' => 'OK', 'Record' => $client->to_array()));
}
else
{
return json_encode(array('Result' => 'ERROR', 'Message' => 'Error Inserting Record =('));
}
});
According to the Laravel docs I've read, you're supposed to use ->to_array() to convert your model to an array, and ::create returns an instance of the model if successfully inserted. I've checked the database, and the records are being inserted just fine.
By default if you were to return an Eloquent model directly it would convert the model to it's JSON representation. This is because the __toString magic method on each model returns the model as JSON by using the toJson method.
As such the model implements both the ArrayableInterface and JsonableInterface. That means you can directly call toJson or toArray on a model.
Now you can mark columns as hidden. This means that when a model is converted into it's array or JSON representation some columns are removed (think publicly accessible API, you don't want passwords showing up!). I'm not totally sure but maybe the ID of your model is being hidden.
At the end of the day, all you need to do is return the instance.
return $client;
It'll be converted to JSON for you automatically.
The to_array() method comes from Laravel 3. Use toArray() in Laravel 4.
I see question similar you try to return data to jquery jtable and same me
Player::orderBy($sort)->paginate($pagesize)->getCollection();
return Response::view(array('Result'=>'OK','Records'=>$player->toArray()));
for try many hour I found solution getcollection pull instance from object and then solve