Eloquent relationship update appropriate database fields in Laravel - laravel

I have BelongsTo model between 3 database (Admins, vendors, and vendor_business_table) table in Laravel. Trying to save the data which comes from HTML form in appropriate database field. My Admin Model looks like below:
class Admin extends Authenticatable
{
use HasFactory;
protected $guard = 'admin';
public function getVendorDetails(){
return $this->belongsTo(Vendor::class, 'vendor_id','vendor_id');
}
public function getVendorBusinessDetails(){
return $this->belongsTo(VendorBusinessDetails::class, 'vendor_id','vendor_id');
}
}
Once all the data is sent from the form I am trying to catch and save the fields. We have only id field is foreign key.
public function editVendorsDetails(Request $request,$id){
if($request->isMethod('post')){
$data = $request->all();
$myModel = Admin::with('getVendorDetails')->find($id);
$myModel->getVendorDetails->fill($data);
$myModel->getVendorDetails->save();
Once I save the form nothing is changed. Am I missing something here? Your help would be highly appreciated.

Would you please replace your code with this code in editVendorDetails()
if($request->isMethod('post')){
$data = $request->all();
$myModel = Admin::with('getVendorDetails')->find($id);
$myModel->getVendorDetails()->create($data);
}

// fill this array which field you want to store like name
protected $fillable = ['name'];
or
protected $guarded = [];
Have a look at is Mass Assignment Documantation.

Related

Eloquent relationship mass assignment $guarded ignored

I have three table in DB, and I have used belongsTo for merging them. My Admins model looks like this :
class Admin extends Authenticatable
{
use HasFactory;
protected $guarded = ['status', 'shop_name', 'vendor_id', 'id'];
protected $guard = 'admin';
public function getVendorDetails(){
return $this->belongsTo(Vendor::class, 'vendor_id','vendor_id');
}
public function getVendorBusinessDetails(){
return $this->belongsTo(VendorBusinessDetails::class, 'vendor_id','vendor_id');
}
}
I need to prevent shop-name field to be saved through form. this field is in the table name : vendor_business_detals (getVendorBusinessDetails).But in this case $guarded only works for Admins table and ignores another relationship tables and fields of them such as shop_name. In short I am struggling to find the way to add $guarded data for VendorBusinessDetails. My controller looks like below:
$business_data = $request->only(['shop_name', 'shop_address', 'shop_phone']);
//dd($business_data);
$myModel = Admin::find($id);
//business table update
$myModel->getVendorBusinessDetails()->update($business_data);
VendorBusinessDetails model:
class VendorBusinessDetails extends Model
{
use HasFactory;
protected $guarded = ['shop_name'];
protected $table = 'vendors_business_details';
}
I don't know why $guraded=['shop_name'] is ignored. Any help would be highly appreciated.
$myModel->getVendorBusinessDetails()->update($business_data);
If you use "getVendorBusinessDetails" as a method, the model isn't initialize. Only the SQL update command runs.
$myModel->getVendorBusinessDetails->update($business_data);
Using "getVendorBusinessDetails" as a field initializes the model. So, it works as you expected.

Laravel Eloquent relationship data retrieve

I have below code to get data from database,
$profile = Profiles::find(1);
$currency = Profiles::find($profile->currency_id)->currency;
Then created a relationship in the model as below,
class Profiles extends Model
{
use HasFactory;
protected $table = 'Profiles';
protected $primaryKey = 'profile_id';
public function Currency()
{
return $this->belongsTo(Currencies::class, 'currency_id');
}
}
class Currencies extends Model
{
use HasFactory;
protected $table = 'Currencies';
protected $primaryKey = 'currency_id';
public function profile()
{
return $this->hasOne(Profiles::class, 'currency_id');
}
}
Problem is that there is only 1 profile and 100 currency, currency_id is a foreign key in Profiles table,
I could not get data and get this error, Trying to get property 'currency' of non-object"
If i use $currency = Profiles::find(1)->currency; then it retrieve first row of Curriencies table which is not required data.
How can I get currency row for that specific profile?
The problem is that the find() method will look for the primaryKey and in your second call the currency_id is not the pk.
Two solution for you:
replace the find by a where clause like so: $currency = Profiles::where('currency_id',$profile->currency_id)->value('currency')
Or a more Laravel way to do it, through the relationship $currency = $profile->currency;

Soft delete in laravel is not hiding record in view

I am using Eloquent soft delete to delete a row in the database. I use function destroy, in database column deleted_at have a date, but this is not hiding deleted records in view.
My code in controller.
$query = Role::join('users', 'roles.id', '=','users.role_id');
$user = User::all();
$users = $query->select('users.*','roles.name as role_name')->paginate(10);
My code in User Model
use SoftDeletes;
use HasFactory;
protected $table = 'users';
protected $guarded = [];
protected $hidden = [
'password', 'remember_token', 'deleted_at'
];
public function roles() {
return $this->belongsTo(Role::class);
}
My code in Models Role
use HasFactory;
protected $table = 'roles';
protected $guarded = [];
public function users() {
return $this->hasMany(User::class);
}
So it seems, the problem here is the join. Soft delete is an Eloquent feature which works on the model itself but not on the joined table. In case you have to join two tables, you have to query yourself to drop out the deleted column. In your case you can do it like
$query = Role::join('users', 'roles.id', '=', 'users.role_id');
$user = User::all();
$users = $query->select('users.*', 'roles.name as role_name')->where('users.deleted_at', null)->paginate(10);
so this will drop out the deleted column. but as you are using relationship, why you have to join yourself?? the relationship will handle that for you. you can simply call like
$roles = Role::with('users')->get();
and you can get every users of a role like
foreach ($roles as $role) {
foreach ($role->users as $user) {
echo $user->attribute;
}
}
and a note for you. you need to pass the foreign key name as the second parameter of the relationship definition as it's not matching the laravel's naming convention.
public function roles() {
return $this->belongsTo(Role::class, 'role_id');
}
and
public function users() {
return $this->hasMany(User::class, 'role_id');
}
if you used eloquent relationship it would worked but now you are using join. the login of eloquent orm is this, you can write your SQL and query it but you have to manually select which do you want or not want(in this case you dont want the records that deleted_at column is filled. but if you use relationships you can have the benefits of soft delete and many other features.

Update Foreign Key with softDeletes()

Hi I've been looking for the similar solution but can't find anywhere. I don't even know if there is one. What I am trying to do is perform a softDelete on one of my model and want to update the user_id in the model with the the id of the user performing the action. I have tried using associate(), it doesn't throw any exception but does not work. I mean the delete is working but id is not updating
Here's what I've tried
public function postDelete(Request $request){
$appointment = \App\Models\emp_appointment::findOrFail($request->appid);
$user = $request->user();
$appointment->user()->associate($user);
$appointment->delete();
}
Here's my Appointment Model
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class emp_appointment extends Model{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function employee(){
return $this->belongsTo('App\Models\employee','emp_id');
}
public function user(){
return $this->belongsTo('App\Models\tb_login','userid');
}
}
PS: There are no problems in the models and no errors anywhere. Only the problem is userid doesn't get updated in the appointment table.
Seems like the delete method isn't saving your change (association)
Try saving first then deleting
public function postDelete(Request $request){
$appointment = \App\Models\emp_appointment::findOrFail($request->appid);
$user = $request->user();
$appointment->user()->associate($user);
$appointment->save();
$appointment->delete();
}
EDIT
public function postDelete(Request $request){
$appointment = \App\Models\emp_appointment::findOrFail($request->appid);
$user = $request->user();
$appointment->user()->associate($user);
$appointment->deleted_at= date('Y-m-d H:i:s');
$appointment->save();
}

Why is save() is changing the model value?

Here is where I save the game:
public function storeGame() {
$player = new Player(['player_name' => Request::get('host_name')]);
$player->save();
$game = new Game(Request::all());
$game->host_id = $player->id;
$game->save();
$player->game_id = $game->id;
$player->save();
return redirect('lobby');
}
Here is the eloquent relationship:
class Game extends Model {
protected $table = 'games';
protected $fillable = ['game_name','password','round_time','num_rounds','num_players','roles_bool'];
protected $hidden = ['password'];
public function host() {
return $this->hasOne('App\Player', 'id');
}
public function players() {
return $this->hasMany('App\Player', 'id');
}
}
The problem is when I save the game, the value of the host id is changing. These are the results of a var_dump() after saving.
$game->host_id:
int 2
$game->host->id:
string '1' (length=1)
Why is this happening and how do I stop it?
Thanks for help in advance.
Duncan - I'm thinking this has something to do with your Host relationship. I don't see a host_id anywhere in your fillable fields on your Games model.
You should have a host_id fillable field on your Games model and then the relationship would look like this:
public function host() {
return $this->hasOne('App\Player', 'host_id');
}
You probably loaded related host object before and it hasn't been "refreshed" after you changed host id. Actually you shouldn't change relations ids directly, there are dedicated methods to do that: http://laravel.com/docs/4.2/eloquent#inserting-related-models

Resources