Eloquent is setting a value to null - laravel

i'm having an error with Eloquent (and Many to Many relationship).
This is my code:
$user = new Users;
$rs = $user
->company()
->where('company_role.users_id', $request->session()->get('usrid'))
->where('code', $request->company)
->first();
The query that Eloquent perform is this one:
select `companies`.*, `company_role`.`users_id` as `pivot_users_id`, `company_role`.`companies_id` as `pivot_companies_id`, `company_role`.`role_name` as `pivot_role_name` from `companies` inner join `company_role` on `companies`.`id` = `company_role`.`companies_id` where `company_role`.`users_id` is null and `company_role`.`users_id` = 1 and `code` = 12345678901 limit 1)"
How is this possible? Do you guys have any idea?
This is my Users model:
class Users extends Model
{
//table associated with model
protected $table = 'users';
protected $primaryKey = 'id';
public function company(){
return $this->belongsToMany('App\Companies','company_role')->withPivot('role_name');
}
}

It was a rookie error
i just changed this:
$rs = $user->company()->where('company_role.users_id',$request->session()->get('usrid'))->where('code',$request->company)->first();
into this:
$rs = $user->find($request->session()->get('usrid'))->company()->where('piva',$request->company)->first();
and everything works as expected.
Thanks to everyone!

First, define the variables
$user_id = $request->session()->get('usrid');
$user = User::find($user_id);
Then, you need to find the user and the companies they are attached, and an individual company with the search params
$companies = $user->company()->get();
$company = $user->company()->where('code', $request->company)->first();

Related

Laravel Eloquent select data from one Model by checking another Model values

I want to select all the Offers with the condition that it is not completed (data not exist on OffersProof OR offers proof status = 0 with multiple where conditions in OffersProof)
List offers that do not have the proof. If proof exists then check the status of it. if that is 0 then show it in the list.
Offers Model
class Offers extends Model
{
protected $table = 'offers';
protected $fillable = [ "name","desc"];
protected $hidden = [];
}
Offers Proof Model
class OffersProof extends Model
{
protected $table = 'offers_proof';
protected $fillable = [ "offer", "user","pub","time","status" ];
protected $hidden = [];
}
Here is the query that I have tried. There are issues in the selection. Not sure this one works as perfect or needs to implement this using relation.
$user = "test";
$pub = "demo";
$offers = Offers::leftJoin('offers_proof', function($leftJoin)use($user,$pub)
{
$leftJoin->on('offers_proof.offer', '=', 'offers.id');
$leftJoin->where('offers_proof.user', '=', $user);
$leftJoin->where('offers_proof.pub', '=', $pub);
$leftJoin->where('offers_proof.status', '!=', 0);
})->where($conditions)->get();
This code returns all the offers. I want to filter the offers that have no proof on the OffersProof table.
Is there any better way to take the data with good performance query and how can I select the offers as per the above requirement.
If I understand you correctly, you want to select offers that are not complete OR offers proof status = 0. I think this code should work.
$user = "test";
$pub = "demo";
$offers = Offers::leftJoin('offers_proof', 'offer', 'offers.id')
->select(*)
->where('offers_proof.user', $user)
->where('offers_proof.pub', $pub)
->where('offers_proof.status', 0)
->where($conditions)
->get();
I have missed the DB::Raw part and one condition to check whether left join data exists.
$user = "test";
$pub = "demo";
$offers = Offers::leftJoin('offers_proof', function($leftJoin)use($user,$pub)
{
$leftJoin->on('offers_proof.offer', '=', 'offers.id');
$leftJoin->where('offers_proof.user', '=', DB::raw("'$user'"));
$leftJoin->where('offers_proof.pub', '=', DB::raw("'$pub'"));
$leftJoin->where('offers_proof.status', '!=', DB::raw("0"));
})->where('offers_proof.user', '=', NULL)->where($conditions)->get();

Laravel MorphMany Relationship - What am I missing?

I have the defaults users table which I've altered to have userable_type and userable_id. I have various models, eg BursaryAdministrator and BursaryProvider and users can belong to either.
BA/BP Model:
public function users() {
return $this->morphMany('App\Users', 'userable');
}
Users Model:
public function userable()
{
return $this->morphTo();
}
During my migration, I've created a default BursaryAdministrator and BursaryProvider and a couple of users. I want to assign them to each:
$bp = \App\BursaryProvider::first();
$user = User::find(2);
$bp->users()->associate($user);
$ba = \App\BursaryAdministrator::first();
$user = User::find(3);
$ba->users()->associate($user);
However, they're not linking as the userable_type / userable_id fields are null. I've tried both 'associate' and 'attach'.
Whats the correct what to do this?
You could try to save() the user after association, i.e.:
$bp = \App\BursaryProvider::first();
$user = User::find(2);
$bp->users()->associate($user);
$user->save()
$ba = \App\BursaryAdministrator::first();
$user = User::find(3);
$ba->users()->associate($user);
$user->save()
Ok, so this was the correct way at the end of the day:
$bp = \App\BursaryProvider::first();
$user = User::find(2);
$user->userable()->associate($bp);
$user->save();
$ba = \App\BursaryAdministrator::first();
$user = User::find(3);
$user->userable()->associate($ba);
$user->save();
Thanks to #dparoli for pointing me in the right direction.

How can i decode json data if i saved in array laravel?

I have 2 two tables: one is an admission and the other is a class table. I am saving class id in admission class field of admission table by json_encode method.
My controller
public function store(Request $request)
{
$inputs = $request->all();
$admission = new Admission;
$admission->school_id = Auth::User()->id;
$admission->admission_classes=json_encode($inputs['admission_classes']);
$admission->save();
}
My index function
public function index(Request $request) {
$school_id= Auth::user()->id;
$admissions= Admission::where('school_id',$school_id)->orderBy('id','desc')->paginate(10);
return view('frontend.index',compact('admissions','active_class'));
}
My view
#foreach($admissions as $i => $admission)
{{ $admission->admission_classes }}
#endforeach
I am getting data in this way:-
["1","2","4","5","6","7","8","9"]
But I want to get in this format:
Nursery,Class 1, Class2, Class3 etc
My class controller
class Classes extends Authenticatable
{
use EntrustUserTrait;
use Billable;
use Messagable;
protected $fillable = [
'name','status'
];
}
You need to save integer value in as json array and do the following code
$integerIDs = array_map('intval', $inputs['admission_classes']);
$admission->admission_classes= json_encode($integerIDs);
public function index(Request $request){
$admissions = DB::select('SELECT a.*, GROUP_CONCAT(c.name) as classes FROM academy as a LEFT JOIN class c ON JSON_CONTAINS(a.classes, CAST(c.id as JSON), '$') WHERE a.school_id =2 GROUP BY a.id');
$admissions = $this->arrayPaginator($admissions, $request);
return view('frontend.index',compact('admissions','active_class'));
}
public function arrayPaginator($array, $request)
{
$page = Input::get('page', 1);
$perPage = 10;
$offset = ($page * $perPage) - $perPage;
return new LengthAwarePaginator(array_slice($array, $offset,
$perPage, true), count($array), $perPage, $page,
['path' => $request->url(), 'query' => $request->query()]);
}
I have not checked the code hope this will help u to continue.......
The best way to achieve this would be to have a one-to-many relationship with App\Classes.
However, since you already have something up and running, I would probably do it like this.
First, I would cast admission_classes to an array. This makes sure that admission_classes will always be casted to an array whenever it is fetched. It makes it easier for us to work with it.
protected $casts = [
'admission_classes' => 'array'
];
Finally, while fetching your admission records, you would also need to map over it and hydrate the Classes from its ids. This is how I'd try to achieve it.
$admissions = Admission::where('school_id',$school_id)
->orderBy('id','desc')
->paginate(10)
->map(function($admission) {
return array_map(function($class) {
$class = Classes::find($class);
return isset($class) ? $class->name : '';
}, $admission->admission_classes);
});
You will notice that I wrapped the Classes::find() method into the optional() helper. This is because, in case, a record is not found, it will not fail.
Finally, to print your class names in your blade, you would do something like this:
implode(',', $admission->admission_classes);

Calling eloquent relation multiple times doesn't return data

I'm having this strange behavior in Laravel 5.1 where when I call the relation of an eloquent model more than once within the same code execution, then the second time it doesn't have the data.
class Items extends Eloquent {
public $table = 'items'
public function subItems() {
return $this->hasMany(Item::class, 'items_id');
}
}
class Item extends Eloquent {
public $table = 'items_item'
public $fillable = ['items_id'];
}
$items = Items::create();
Item::create([
'items_id' => $items->id,
]);
Item::create([
'items_id' => $items->id,
]);
// works
$first = $items->subItems;
// no data
$second = $items->subItems;
// works
$third = $items->subItems()->get();
Is this normal behavior? Do i have to somehow reset something before calling the relation again?
I don't know the purpose of your repeated same action. If your $first,$second,$third variables are in same function, don't repeat it again.
Instead use,
$first = $items->subItems;
$second = $first;

Cannot instantiate abstract class Illuminate\Database\Eloquent\Model - Laravel 4

I'm trying to extract the building of an Eloquent query as I want to reuse this code with many different models. In the controller, I have:
$inputs = Input::all();
$user = new Eloquent;
$result = Helpers::buildQuery($user, $inputs);
And the Helpers class:
<?php namespace ArgumentClub;
class Helpers {
public static function buildQuery(Eloquent $model, $inputs)
{
$limit = isset($inputs['limit']) ? $inputs['limit'] : 10;
$offset = isset($inputs['offset']) ? $inputs['offset'] : 0;
list($orderCol, $orderBy) = isset($inputs['order']) ? explode(",", $inputs['order']) : explode(",", 'created_at,DESC');
$result = $model
->orderBy($orderCol, $orderBy)
->skip($offset)
->take($limit)
->get();
return $result;
}
}
So, how can I pass in the model and have it query that model, returning the Eloquent collection?
Eloquent (which is an alias for Illuminate\Database\Eloquent\Model) is an abstract class. You can't instantiate it. Instead you have to do this:
$inputs = Input::all();
$user = new User;
$result = Helpers::buildQuery($user, $inputs);
The type restriction buildQuery(Eloquent $model, $inputs) will still work fine because User extends Eloquent and therefore is accepted by the method.
A little sidenote, you might also want to think about creating a base model to extend Eloquent and share functionality between all models.
You just have to pass your model class for exemple a User model which extend eloquent:
$inputs = Input::all();
$user = new User;
$result = Helpers::buildQuery($user, $inputs);
Just add the ungaurd() and regaud() before and after your seeder classes in run() method of DatabaseSeeder.php
\Illuminate\Database\Eloquent\Model::unguard();
//$this->call(UsersTableSeeder::class);
\Illuminate\Database\Eloquent\Model::reguard();
This solved my problem.

Resources