Laravel Eloquent update not updating one field - php

I am using Laravel API along with VueJS Frontend application. I send axios POST call along with some information which the user puts about himself. In the backend, I take that data and update the user record in the MySQL database.
This is my backend code:
$user = User::where(['logintoken' => $request->login_token, 'remember_token' => $request->remember_token])->first();
if (!$user) {
$status = 404;
$response = ['status' => false, 'message' => 'User not found.'];
} else {
$affectedRows = $user->update([
'country' => $request->input('country'),
'city' => $request->input('city'),
'state' => $request->input('state'),
'dob' => $request->input('dob'),
'language' => $request->input('language'),
'street' => $request->input('street'),
'house' => $request->input('house'),
'avatar' => $request->input('avatar'),
'birthplace' => $request->input('birthplace'),
'type' => $request->input('userType'),
'bio' => $request->input('bio'),
'zip' => $request->input('zip'),
'has-completed-profile' => 1
]);
if (!$affectedRows) {
$response = ['status' => false, 'message' => 'Error updating'];
$status = 500;
} else {
$response = ['status' => true, 'message' => 'User updated successfully', 'updated_record' => $user, 'request' => $affectedRows, 'zip' => $request->input('zip')];
}
}
Now, this code is working perfectly fine, except, it is not updating the zip field. I console.log() the response in VueJS side, and I see that the zip value is correct and also the data type fo zip field in the DB is string.
Still, this is not working for the zip column. When I had created the users migration, there was no zip column, but after some time, when I needed it, I created another migration and used it to alter the table to insert the zip field.
Any idea on why it isn't working?

You need to add that field in Respective Model class.
This should solve your problem.
$fillable serves as a "white list" of attributes that should be mass assignable. So, to get started, you should define which model attributes you want to make mass assignable. You may do this using the $fillable property on the model. For example, let's make the zip attribute of our User model mass assignable:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['zip', // your rest column names];
}
This example should help you sort your problem.
Here is the documentation.

You probably missed zip in you model's $fillable.
So add it, it should look like this:
protected $fillable = [
'country', 'city', 'state', 'dob', 'language', 'street', 'house', 'avatar', 'birthplace', 'type', 'bio', 'zip', 'has-completed-profile'
];
Find documentation here

Related

Magento 2 - How to retrieve column values as custom attribute options?

I have a working module with CRUD in admin, now I want to add a custom attribute for products, but options of that attribute should be a values from existing DB table, but every tutorial on the web is teaching how to hardcode those attribute options, so how can I do that?
Thanks everyone!
I have found in Magento 2 documentation, how to create a custom attribute, created InstallData with the attribute, but need to correct the provided code of the Source model, so that will get values from my DB table
namespace Learning\ClothingMaterial\Model\Attribute\Source;
class Material extends
\Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
{
/**
* Get all options
* #return array
*/
public function getAllOptions()
{
if (!$this->_options) {
$this->_options = [
['label' => __('Cotton'), 'value' => 'cotton'],
['label' => __('Leather'), 'value' => 'leather'],
['label' => __('Silk'), 'value' => 'silk'],
['label' => __('Denim'), 'value' => 'denim'],
['label' => __('Fur'), 'value' => 'fur'],
['label' => __('Wool'), 'value' => 'wool'],
];
}
return $this->_options;
}
}

laravel - inserting id from one table to another right after submitting a form

Since I'm new in Laravel (started using this framework 2 weeks ago), I'm having a hard time inserting an id from one table to another right after submitting a form.
The scenario is that I have a form and what I wanted is that the id (p_id) of the newly submitted data from the 1st table (packages table) will be inserted to the 2nd table (itineraries table). Below are the codes of my controller and my model:
Controller
public function store(Request $request){
request()->validate([
'packageName' => 'required',
'adultPrice' => 'required',
'childPrice' => 'required',
'infantPrice' => 'required',
'excessPrice' => 'required',
'type' => 'required',
'inclusions' => 'required',
'additionalInfo' => 'required',
'reminders' => 'required',
'photo' => 'required',
'tags' => 'required',
'noOfDays' => 'required',
'day' => 'required',
'time' => 'required',
'destination' => 'required'
]);
Packages::create($request->all());
Itinerary::create($request->all());
return redirect()->route('Agent.Packages');
}
Itinerary Model
class Itinerary extends Model{
public $fillable = [
'noOfDays',
'day',
'time',
'destination',
];
}
The create method returns the saved model instance.
$package = Packages::create($request->all());
After that you can use it to populate the Itinerary table however you want.
$itinerary = new Itinerary();
$itinerary->package_id = $package->id;
// Populate other fields
$itinerary->save();
Since you're new to Laravel, I would propose to use the ->save() method to populate it. In my opinion, it's clearer in telling what you want to do in the code.
To insert Data from first table to second table,
First of all you need to get the last Insert Id.
Change your code as follows:
$package = Packages::create($request->all());
$p_id = $package->id; // You will get your Id.
// Later you need to add it to below method.
$data = array_merge($p_id,$request->all()); // I`m not sure about this line...
Itinerary::create($data);

ZF2 + Doctrine 2: Hydrate related objects via ZF2 Form

Our application (Zend Framework 2 + Doctrine 2) has an Order entity which references its related objects like BillingAddress and so on. We have implemented a REST API to create and update orders. The data is passed to this API as an associative array and the data of the referenced objects can be encapsulated inside this array. I. E. the data received by the Order API looks like this
$data = [
// This is an attribute of the Order entity itself
'remarks' => 'Urgent order',
// This is the data of the referenced BillingAddress
'billing_address' => [
'firstname' => 'Barry',
'lastname' => 'Fooman'
]
];
First thing to note about this is the fact that the given BillingAddress can either be new or an existing one! In the latter case an id would be part of the billing_address data.
Using the DoctrineObject hydrator
$hydrator = new DoctrineObject($entityManager);
$hydrator->hydrate($order, $data);
Doctrine takes care of updating or creating the referenced objects automagically. This is how we are doing it so far: Take the received data, do a little processing to sanitize and validate the data and call the hydrator.
However we now want to use Zend\Form\Form for easy sanitizing of the received data. Setting up a Form for the simple attributes of the Order is pretty easy
class OrderForm
extends \Zend\Form\Form
{
public function __construct()
{
parent::__construct('order');
$this
->add([
'name' => 'remarks',
'type' => 'text'
]);
}
}
But I struggle with the referenced objects. How do I set up the form so that the referenced objects are created or updated by Doctrine just like using the hydrator directly? Do I have to create a "sub-form/fieldset"?
Yes, you can create a fieldset for the BusinessAddress entity and then add it to the OrderForm.
use Zend\Form\Fieldset;
class BusinessAddressFieldset extends Fieldset
{
public function __construct($entityManager)
{
parent::__construct('businessAddress');
$this->add(array(
'name' => 'firstName',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'First Name',
),
'attributes' => array(
'type' => 'text',
),
));
$this->add(array(
'name' => 'lastName',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'Last Name',
),
'attributes' => array(
'type' => 'text',
),
));
}
}
And then add the field set to your OrderForm:
class OrderForm
extends \Zend\Form\Form
{
public function __construct()
{
parent::__construct('order');
// add fields
$this->add(new BusinessAddressFieldset());
}
}
Make sure that the name of the fieldset that you set, match the name of the reference and that you set the form hydrator.

yii2: how to add a column in index ( GridView ) with innerjoin

i want add a column in GridView::widget
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'owner_id',
'situation',
'address',
[
// 'attribute' => 'address',
'format' => 'html',
'label' => 'Image',
'value' => function ($data) {
return Html::img('http://iicity.ir/' . $data['address'],
['width' => '60px']);
},
],
'slideshow_text',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
i want add name of 'owner_id', from another table
name is in ( account )table
table :
id=1 name=jack
id=2 name=sara
use app\models\Account;
...
[
'attribute' => 'owner_id',
'value' => function ($model) {
$info = Account::findOne(['id' => $model->owner_id]);
return isset($info->name) ? $info->name : $model->owner_id;
},
],
#suibber's accepted answer:
[
'attribute' => 'owner_id',
'value'=>function ($model) {
$info = Account::findOne(['id' => $model->owner_id]);
return isset($info->name) ? $info->name : $model->owner_id;
},
],
has some problems:
1) Constructing SQL queries logic is exposed in view, so MVC princple is violated. View is only for displaying data.
2) All related owner's data is lazily loaded, that means amount of queries is multiplied by number of displayed rows in the table.
3) Why displaying owner_id if the record doesn't exist? That simply means the data is corrupted. You should not even check owner for existence here because logically it should always exist, you need to perform validation before saving and don't delete data with manually written SQL queries (or using GUI tools) in case of missing foreign keys.
4) Lack of autocompletion for IDE.
The Yii2 way of solving this problem is obviously using relations.
Add this to your model:
<?php
namespace app\models;
use app\models\User;
use yii\db\ActiveRecord;
/**
* ...
*
* #property User $owner
*/
class Picture extends ActiveRecord
{
/**
* #return \yii\db\ActiveQuery
*/
public function getOwner()
{
return $this->hasOne(User::className(), ['id' => 'owner_id']);
}
}
Then to display owner name in GridView:
[
'attribute' => 'owner_id',
'value'=>function ($model) {
/* #var $model app\models\Picture */
return $model->owner->name;
},
],
Or just:
'owner.name',
The advandtages are clear - it's framework way, code is shorter, more readable, data can be eagerly loaded using ->with('owner') in your ActiveQuery for GridView.
By the way, no INNER JOIN is needed. Related data is fetched with separate SQL query. If, for some reason, owner is optional and can be not existing in some records, use:
[
'attribute' => 'owner_id',
'value'=>function ($model) {
/* #var $model app\models\YourModel */
return $model->owner ? $model->owner->name : null;
},
],
Working with related data is well covered in official docs, so it's pretty basic question. Check the docs first.

Laravel model inheritance

I am using the Toddish/Verify library for Laravel as it includes 99% of what I need for my project. All I need is to add some fields.
I have added them in a migration, and I want to add them also to mass creation:
use Toddish\Verify\Models\User as VerifyUser;
class User extends VerifyUser
{
public function __construct () {
array_merge ($this->fillable, array(
'salutation', 'title', 'firstname', 'lastname', 'phonenumber', 'mobilenumber'
));
}
}
However, when I run my creation test:
public function testUserCreation () {
$user = User::create(
[
'username' => 'testusername',
'email' => 'email#test.com',
'password' => 'testpassword',
'salutation' => 'MrTest',
'title' => 'MScTest',
'firstname' => 'Testfirstname',
'lastname' => 'Testlastname',
'phonenumber' => 'testPhoneNumber',
'mobilenumber' => 'testMobileNumber',
]
);
$this->assertEquals($user->salutation, 'MrTest');
$this->assertEquals($user->title, 'MScTest');
$this->assertEquals($user->firstname, 'Testfirstname');
$this->assertEquals($user->lastname, 'Testlastname');
$this->assertEquals($user->phonenumber, 'testPhoneNumber');
$this->assertEquals($user->mobilenumber, 'testMobileNumber');
}
I get this:
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 19 users.username may not be NULL (SQL: insert into "users" ("updated_at", "created_at") values (2014-03-03 09:57:41, 2014-03-03 09:57:41))
in all tests that involve user creation, as if it had forgotten about the parents attributes when saving the model.
What am I doing wrong?
The problem is that you're overriding what I assume is the Eloquent constructor, so the values are never getting passed.
Change __construct to look like the following.
public function __construct(array $attributes = array())
{
parent::__construct($attributes);
array_merge ($this->fillable, array(
'salutation', 'title', 'firstname', 'lastname', 'phonenumber', 'mobilenumber'
));
}
The Model::create method will actually create a new instance of the model and pass the array into the __construct. You're overriding this and preventing it from passing the information through.
Note If you decide to override core methods like you've done here, always check inheritance and make sure you aren't breaking anything.

Resources