Laravel update creates a new record - laravel

AM trying to update existing record with eloquent via
return Users::where('id', $id)
->update(['names' => $request->input("name")]);
But the above creates a new record. What am i missing on this?
I would like this to be one line as above.

You have missed many things, such as coding convention of Laravel. Indeed, we usually create model in singular firm but you created "Users". Instead of "Users" you can create "User" model. And the syntax is also incorrect. So you can follow the below code. It should work if you have created table, model and controller in a correct way.
return User::where('id', $id)->first()->update(['name' => $request->input("name")]);
Or
return User::findOrFail($id)->update(['name' => $request->input("name")]);

Related

Laravel delete relationship and create new in one way?

Hi guys is it possible to do following code in one way?
$Project->deadline()->delete();
$Project->deadline()->create($deadline);
Project Model:
public function deadline()
{
return $this->hasOne('App\Models\UserProjectDeadline','projects_id','id');
}
Seems there's no methods for deleting and creating in one line of code, but Laravel offer functions updateOrCreate(array $attributes, array $values = []) that can be used for hasOne relationships.
$Project->deadline()->updateOrCreate($attributes, $deadline); // To update based on the attributes
Or if you want to change/update all the data without any specified attributes
$Project->deadline()->updateOrCreate([], $deadline); // To update all the data

Laravel Model factories, one to many relationship without database access

For my tests (Laravel 6) I am trying to use factories with make(), in order to bypass the DB operations just creating a new instance of the model.
Now, I am having an headache to make things work with my one to many relationship.
A skeleton of my code just to have an overview:
class Fine extends Model {
// Other things here
public function articles()
{
return $this->hasMany('App\Model\Article');
}
}
where Article does not have any other relationships.
Now, I would like to create a Fine factory to create an instance in which I can parse $fine->articles, all without any database interaction.
Here's the basic Fine factory that works (without using articles):
$factory->define(Fine::class, function (Faker $faker) {
return [
"id" => 10,
Fine::FIELDONE => 'xxx',
Fine::FIELDTWO => 'yyy',
];
});
that I use with  $fine = factory(Fine::class)->make(); .
Now I need to "prefill" articles. I have tried with  hydrate() but it does not work.
I have tried with afterMaking() with different combinations of code:
$factory->afterMaking(Fine::class, function (Fine $fine, Faker $faker) {
$articles = factory(\App\Model\Article::class, 3)->make([\App\Model\Article::FINE_ID => $fine->id]);
// TEST WITH SAVEMANY: $fine->saveMany(factory(\App\Model\Article::class, 10)->make());
// SAME WITH CREATEMANY
// TEST WITH HYDRATE: $multa->articles()->hydrate([$article]);
// $multa->load('articles');
});
Just to make a point I have tried different roads but, I admit, I am a bit lost.
Basically I end up with the classical
Illuminate\Database\QueryException: SQLSTATE[42S02]: Base table or view not found
error, so I am still accessing the database.
Now, I am starting to think that factories are a proper choice only if at the end one is going to store data on the database (I am sure that saveMany() is going to work if I use create() and not make()).
Can you please give me an hint on how to accomplish this task? If factories are not the right way to do it I am more than open to change my choice, too.
Thanks in advance!
Lorenzo
You can set this information on a non existing model instance if you really have to:
$fine->setRelation(
'articles',
factory(\App\Model\Article::class, 3)->make()
)
It depends what you plan on doing with this model and its relationship since there are no IDs set so they are not really related in that way.

How to use create method with variables in Laravel

How can i define create method with variables and model in laravel? Like this:
public function createMethodName($variable, $variable2)
{
\App\ModelName::create([...]);
}
You have to just insert the passed variables in the array like:
// include model at the top of your file:
use \App\Models\ModelName;
public function createMethodName($variable1, $variable2)
{
$my_stuff = ModelName::create([
‘something’ => $variable1,
‘something_else’ => $variable2,
]);
}
Also, do not forget to make some of your Model fields fillable (fields which are included in the array) in your Model, if you want to save values to the table with using create(). Check the Reference about this:
https://laravel.com/docs/8.x/eloquent#mass-assignment
Short update:
Maybe I misunderstood your question a bit since according to your new comments under your question it is getting clearer that you maybe first would like to create a Table with Schema::create() method (which is a totally different part of the fun). Reference:
https://laravel.com/docs/8.x/migrations#creating-tables
Then after you created your Table, you can create a Model using artisan like:
php artisan make:model ModelName
Reference:
https://laravel.com/docs/8.x/eloquent#defining-models
and then you can use ModelName::create() method in your Controller as I gave it above to saving your data into your Table. So you should study these steps a bit more if it is the case.

laravel/elequent - models and relations

I trying to learn laravel and to do some tests/demo apps. I've struggling now with laravel/eloquent tables relations. And I need advice.
I have 3 models [Application, Term, AppState] and their tables applications[id, terms_id, appStates_id, and other cols ], terms[id, startDate, endDate, ...], app_states[id, caption]
Application.php
public function term()
{
return $this->belongsTo('App\Term');
}
public function appState()
{
return $this->belongsTo('App\AppState');
}
in Term.php and AppState.php i have:
public function applications()
{
return $this->hasMany('App\Application');
}
How I can get let's say "caption"/"startDay"+"endDate" in blade for each application? I can get their ids $app->terms_id/$app->appStates_id in foreach loop, but i want get caption value from app_states table.
Has to be this relations also specified in migrations? In some tuts is mentioned, that is not needed in case i want to handle it only in laravel.
Thanks for advice
You can access a model's relationship values by calling the relationship method like a property.
$application = Application::find(1);
$application->term->startDate;
$application->term->endDate;
$application->appState->caption;
Also your relationship with AppState is wrong, since your foreign key doesn't follow a snake_case typing, you'll need to provide the appropriate key for it
public function appState()
{
return $this->belongsTo('App\AppState', 'appStates_id');
}
You might also want to check terms_id as well since the model name (Term) is singular but the foreign key is plural.
Has to be this relations also specified in migrations? In some tuts is mentioned, that is not needed in case i want to handle it only in laravel.
Well, yes, you don't need to if Laravel will only be the one accessing that database. But if any cases in the near future you decide to migrate to a different framework or use the same database in another application, it's better to include these relationships in the migration. Also a database administrator would probably cringe if you don't.
So provided your relationships are correctly setup, you can access them anywhere you have an instance of that model.
So for example, lets say you have passed a collection of applications to your view ($apps):
#foreach($apps as $app)
{{ $app->term->startDate }}
{{ $app->term->endDate }}
{{ $app->appState->caption }}
#endforeach
Important Note: We are accessing the Eloquent relationship using ->appState rather than ->appState(). The later is actually accessing a Query Builder instance and has some more advanced use cases

Laravel Backpack : Storing Belongs To Many relationships using custom view

I have a flight class and this flight has a custom view field like so:
This represents a belongs to many relationship which stores website_id / flight_id and pricing as pivot data in a pivot table.
The custom view uses JS to send this data back to the controller in this format:
{"1":{"price_adult":"434","price_child":"545"},"2":{"price_adult":"323","price_child":"324"},"3":{"price_adult":"434","price_child":"43"}}
Trying to send this data with the request doesn't create the relations fields, and because I do not have a flight ID at the point of creating this within the controller I can not loop this JSON to make the relations manually.
Can anyone point out what the best course of action is or if there is support for this? I took a look at the docs but they are woefully short and patchy in terms of being much help.
EDIT:
I should have said I can probably make this work using a custom name attribute on the model for the relation, then add a set mutator to loop this data and update the prices relation but I don't want to go down this route if there is support for this I am missing out of the box in backpack.
EDIT2:
Someone asked about the relation:
$this->belongsToMany(Website::class, 'website_pricing')->withPivot('price_adult', 'price_child');
This is working fine its not a problem with the relation working its how can I get backpack to store the data as a relation when the flight has no ID yet, or how can I pass the data I posted above in such a way that the backpack crud controller can handle it?
You may need to create a flight first, if no flight id is being provided. Can you explain the database relational structure more?
Basically thought I should post what I did because no one could provide an answer to this.
So basically you have to copy the store / update functions from the parent, changing a few lines.
$this->crud->hasAccessOrFail('create');
// fallback to global request instance
if (is_null($request)) {
$request = \Request::instance();
}
// replace empty values with NULL, so that it will work with MySQL strict mode on
foreach ($request->input() as $key => $value) {
if (empty($value) && $value !== '0') {
$request->request->set($key, null);
}
}
// insert item in the db
$item = $this->crud->create($request->except(['save_action', '_token', '_method']));
$this->data['entry'] = $this->crud->entry = $item;
// show a success message
\Alert::success(trans('backpack::crud.insert_success'))->flash();
// save the redirect choice for next time
parent::setSaveAction();
return parent::performSaveAction($item->getKey());
Basically any line which references a function in the parent class using $this->method needs to be changed to parent::
This line is what I used to submit the relations JSON string passed to the controller as relations $item->prices()->sync(json_decode($request->input('prices'), true));
This is done after the line containing $item = $this->crud->create as the item id that just got stored will be available at that point.

Resources