Laravel model relationships Class not found - php

In Laravel I just started with models and I have this database structure:
users
id | username | password | group | //(group is the id of the group)
groups
id | groupname |
group_pages
group_id | page_id | create | read | update | delete
pages
id | pagename
I am trying to check if the user can create/read/update/delete on the page he's on.
So I have 4 Models for this at the moment: Users, Pages,Group_pages and Groups. So in the models, I define the relationships like so:
User model:
public function group()
{
return $this->belongsTo('group', 'group', 'id');
}
Group Model:
public function users()
{
return $this->hasMany('users', 'group', 'id');
}
public function group_pages()
{
return $this->hasMany('group_pages', 'group_id', 'id');
}
I am using this in my controller like this:
$group_id = User::find(Session::get('user_id'));
$crud = Group::find($group_id->group)->group_pages()->first();
As described in the documentation.
but this is giving me the error:
Class group_pages not found
What is going wrong here?
I'm not sure about assigning the keys in the relationships.
I know this:
One to One Inverse:
return $this->belongsTo('class', 'local_key', 'parent_key');
One to Many:
return $this->hasMany('class', 'foreign_key', 'local_key');
I dont know about the One to Many Inverse. I know it's: return $this->belongsTo('table');, but I dont know about the keys.
Group_pages model:
class Group_pages extends Eloquent {
public function pages()
{
return $this->belongsTo('pages', 'id', 'group_id');
}
public function group()
{
return $this->belongsTo('group', 'id', 'group_id');
}
}

Model files should be named singularly and in camel-case, i.e. User, Page, Group. A model representing the join between users and groups isn’t necessary.
Then when it comes to defining the relationships, the first parameter is the class name of the model:
class User {
public function group()
{
return $this->belongsTo('Group', 'local_key', 'parent_key');
}
}
You’re making life difficult for yourself by going against Laravel’s conventions.
If you name your columns as per Laravel’s conventions, you then don’t need to specify them in your relationship definitions either. So your users table should have a column named group_id that’s a foreign key referencing the id column in your groups table. Your relationship can then be expressed like this:
class User {
public function group()
{
return $this->belongsTo('Group');
}
}
A lot more succinct and easier to read, and you don’t have to remember which way around the local and foreign column names go.
You can read more about the conventions Laravel uses for model and relation names in the official documentation: http://laravel.com/docs/master/eloquent#relationships

You defined your relationship with a model-class that does not exists.
To solve this, create a group_page-model (or even better GroupPage) and change the corresponding relationship (return $this->hasMany('GroupPage', 'group_id', 'id'); within your Group-model.
Then fix the relationship in your User-model:
public function group() // typo! not groep..
{
return $this->belongsTo('group', 'group'); // remove id, you do not need it
}
Then there is a problem with your controller code which might be fixable like that:
$group_id = User::find(Session::get('user_id'))->group()->id;
$crud = Group::find($group_id)->group_pages()->first();
I always like to recommend Laracasts to peopel who are new to Laravel (i hope you do not know this yet). The basic screencasts are all free (laravel 4 from scratch and laravel 5 fundamendals) and you will lern very fast in no time! Specifically, have a look at the episode on Eloquent Relationsships.
I also strongly recommend sticking to conventions
use the column-name group_id on the users-table for the group-foreign-key).
Classnames should be PascalCase -> Group, not group, and when commiting them as parametes, stick to it (belongsTo('Group'))...
This makes life much easier!
Finally
Be aware that there might be packages for what you are trying to achieve. One that comes to my mind is Entrust.

You're making your life hard with this code and thus you can't make it work.
Check this out first:
// This is User model, NOT group_id
$group_id = User::find(Session::get('user_id'));
Next:
public function group() // I suppose groep was typo, right?
{
// having relation with same name as the column
// makes Eloquent unable to use the relation in fact
return $this->belongsTo('group', 'group', 'id');
}
So, here's what you need:
// User model
public function group()
{
return $this->belongsTo('Group', 'group_id'); // rename column to group_id
}
// Group model
public function pages()
{
return $this->belongsToMany('Page', 'group_pages')
->withPivot(['create', 'read', 'update', 'delete']);
}
Then:
$user = User::find(Session::get('user_id')); // or use Auth for this
$page = $user->group->pages()->find($currentPageId);
// now you can access pivot fields:
$page->pivot->create;
$page->pivot->update;
... and so on

Related

Laravel : Use Pivot table to get group with their respective roles

I'm trying to get All roles in a user group in eloquent style.
//this function is defined in the ModelUserGroup
public function roles(){
return $this->hasMany(ModelGroupRole::class, 'group_id','id');
}
I'm trying to get all roles like this:
ModelUserGroup::with('roles')->get(),
I also tried ->hasManyThrough but it is not working for me.
I need all roles data like id,name, etc. using with.
Looks like you need a belongsToMany relationship.
In your UserGroup model.
public function roles()
{
// Assuming your role model is named ModelRole...
return $this->belongsToMany(ModelRole::class, 'group_role', 'group_id', 'role_id');
}
Now you can do the following:
$group = ModelUserGroup::with('roles')->first();
dd($group->roles); // will be a collection of ModelRole's
Answered on my phone so there may be syntax errors.
As stated here in the many to many section, you have got to define the relationships as the follwing:
in User_Group :
public function roles(){
return $this->belongsToMany('App\Pathto\Role', 'group_role','group_id','role_id');
}
in Role:
public function user_groups(){
return $this->belongsToMany('App\Pathto\UserGroup', 'group_role', 'role_id', 'group_id');
}
Edit: ModelUserGroup::with('roles')->get() should work just fine then.
(of course, change pathto with your path to the models.)

Laravel get model with relation's pivot condition

I need to get all appeals, that have appeal_stage.expiration_date less than NOW().
Now I have following solution:
public function scopeExpired($query) {
$query->join('appeal_stage', 'appeals.id', 'appeal_stage.appeal_id')
->where('appeal_stage.expiration_date', '<=', new Expression('NOW()'));
}
but resulted model dump shows that joined table is recognized as pivot table:
So, I want to ask - Is there some more convenient way to perform this request?
My suggestions is use Illuminate\Database\Eloquent\Relations\Pivot somehow, bu I do not quiet understand, how Pivot can be used here.
UPD 1
Models has next relations:
public function stages()
{
return $this->belongsToMany(Stage::class)->withPivot('prolongated_count', 'expiration_date')->withTimestamps();
}
public function appeals() {
return $this->belongsToMany(Appeal::class);
}
You should be able to do something like this:
$appeal->stages()->wherePivot('expiration_date', '<', $now)->get()
You should create relationship in appeal model
public function stages()
{
return $this->belongsToMany(Stage::class,'appeal_stage','appeal_id','stage_id')->wherePivot('expiration_date','<',Carbon::now())->withTimestamps();
}
In belongs To Many relationship second argument is your Pivot table name

Laravel belongsToMany not returning results

I have the following schema set up:
users:
id
departments:
id
department_user:
id
department_id
user_id
I also have the following relationships set up:
User Model
public function departments()
{
return $this->belongsToMany('App\Resources\Eloquent\Models\Department', 'department_users');
}
Department Model
public function users()
{
return $this->belongsToMany(User::class, 'department_users');
}
For some reason, when I am trying to access through the user model $user->departments, it doesn't work - but $department->users does.
Outputting the eloquent query is as follows:
select `departments`.*, `department_users`.`user_id` as `pivot_user_id`, `department_users`.`department_id` as `pivot_department_id` from `departments` inner join `department_users` on `departments`.`id` = `department_users`.`department_id` where `department_users`.`user_id` is null
I can't seem to figure out why it is looking to see if department_users.user_id is null, when it should be looking for the user's id.
Any ideas?
Why don't you set up your models like it is suggested in the documentation here:
So your models would look something like this:
User Model
public function departments()
{
return $this->belongsToMany('path\to\your\model\Department');
}
Department Model
public function users()
{
return $this->belongsToMany(path\to\your\model\User);
}
Eloquent will join the two related model names in alphabetical order.So you don't need extra arguments when defining your relationship and Laravel also by default, makes model keys present on the pivot object. And then you can do something like this:
$department = path\to\your\model\Department::find(1);
foreach ($department->users as $user) {
echo $user;
}
For some reason, if I make the relationship the following - it works.
return $this->belongsToMany(Department::class, 'department_users')->orWhere('department_users.user_id', $this->id);
If anyone knows why, please let me know

Laravel 5.2 hasManyThrough relationship issue

I have 3 tables: orders, codes, events
I want to be able to pull all events that an order has, but there's an intermediary table that acts as a pivot table. I've been trying to use hasManyThrough and belongsToMany (along with withPivot) without any luck.
Examples:
public function events()
{
return $this->belongsToMany('events'); // tried this, fails
return $this->hasManyThrough('events', 'codes'); // tried this, fails
return $this->hasManyThrough('events', 'codes', 'event_id', 'id'); // tried this, fails
}
Any pointers would be great!
That's a belongsToMany setup. First, the first parameter is the name of the related class. Second, since your pivot table doesn't follow the Laravel naming conventions, you need to specify the name of the pivot table in your relationship definition:
public function events()
{
// first parameter is the name of the related class
// second parameter is pivot table name
return $this->belongsToMany(Event::class, 'codes');
}
With this setup, you can do:
// get an order
$order = Order::first();
// has all the events related to an order
$events = $order->events;
There are many ways to do this. I will show a one you can get it done.
In Order.php model
public function codes(){
return $this->has('App\Http\Code');
}
In Code.php model
public function orders(){
return $this->belongsTo('App\Http\Order');
}
public function events(){
return $this->hasMany('App\Http\Event');
}
In Event.php model
public function codes(){
return $this->belongsTo('App\Http\Code');
}
Then in you Controller, call them to get required data.
In your case you can do it like below:
$orders = Order::with(['codes' => function($q){
$q->with('events');
})->get();
May be you can get them with nested manner(not sure about this because i didn't tried before posting):
$orders = Order::with('codes.events')->get();
put return $orders; in your controller to see the query.
Enjoy!

Laravel Eloquent Joins

I have below query in core php:
SELECT DISTINCT device_tocken FROM push_details JOIN users ON users.id=push_details.user_id
I have to integrate it in laravel 4
Application already have User extends Eloquent class
I created Push_details class as below
class Push_details extends Eloquent {
public $table = 'push_details';
public function User() {
return $this->hasMany('\User','id');
}
}
Table : users
Primary key : id
Table: push_details
Primary key: id
Foreign key: user_id belongsTo('users.id');
But i m not able to get expected result.
One more thing i didn't write anything in User's model yet.
Only way to join table is.. to join it, as Eloquent relations don't work using joins but separate queries with WHERE IN clauses. So this will do:
DB::table('push_details')
->select('device_tocken')
->distinct()
->join('users','users.id','=','push_details.user_id')
->get();
Above will return array of stdObject's so or if you need Eloquent Collection with Eloquent models as a result replace DB::table('push_details')->select... with PushDetails::select...
Now, correct your relations, as they are wrong:
// PushDetails model (as previously stated, I suggest renaming it to StudlyCase)
public function user() {
return $this->belongsTo('\User','user_id'); // user_id is may be omitted here
}
// User model
public function pushDetails() {
return $this->hasMany('\PushDetails','user_id'); // user_id is may be omitted here as well
}
In your User model, you need to link back to the PushDetails model, like so
class User extends Eloquent {
public function push_details() {
return $this->belongsTo('PushDetails');
}
}
Use CamelCase for Class names, because laravel has several functions, in which CamelCase are changed to snake_case
Change
public function User() {
return $this->hasMany('\User','id');
}
to
public function users() {
return $this->hasMany('User');
}
See the docs 'Eloquent ORM' for more...

Categories