Cakephp - save data to relation model - php

I've got three models: users, groups and user_groups
users table: id | alias | password ...
groups table: id | name ...
user_groups table: id | user_id (fk users table) | group_id (fk groups table) ...
In my groups controller, I receive data about available groups and the member:
public function edit($id)
{
if (!$id) throw new NotFoundException(__('Unknown Group'));
//All available groups with members
$group = $this->Groups->find('all', [
'contain' => 'Users'
]);
//Only the group + members with the requested id
$member = $this->Groups->get($id, [
'contain' => 'Users'
]);
if (!$group) throw new NotFoundException(__('Group does not exist'));
if ($this->request->is(['post', 'put'])) {
$this->Groups->patchEntity($group, $this->request->data);
if ($this->Groups->save($group)) {
$this->Flash->success(__('Group successfully updated'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Failed to update group'));
}
$this->set('group', $group);
$this->set('member', $member);
}
I'm trying to build a view containing two selectboxes, one for the users that are already member of the group and one for the remaining (not members) users.
When it comes to data saving to the relation model (user_groups) I'm totally helpless.
Do I have to use specific variable names / input field names?
How to serve the data so the controller knows where to save it?
Thanks in advance and sorry for that noob questions, I'm new to the whole framework thing.

Related

Problem with fetching data from database in one to many polymorphic relations in Laravel

I have one to many polymorphic relationship in Laravel and I am trying to fetch data using eloquent query. I have Favorite model with favorites table
id user_id favoritable_id favoritable_type
1 17 1 App\Models\ProfileImage
2 10 1 App\Models\PostVideo this is some other model
and profile_images table with
id user_profile_id title path
1 17 etc etc
I need to fetch all profile_images from profile_images table that correspond to data in favorites table. So id from profile_images to match favoritable_id, user_profile_id to matches user_id and favoritable_type to match App\Models\ProfileImage from favorites table. Any help is appreciated. Here is my code.
Controller
public function getProfileImages()
{
$profileimage = ProfileImage::whereColumn('id', 'favoritable_id')->first();
// I AM BASICALLY STUCK HERE WITH $profileimage !!!
$favoriteProfileImages = $profileimage->favorites()->where([
'user_id' => auth()->id(),
'favoritable_id' => $profileimage->id,
'favoritable_type' => ProfileImage::class
])->get();
return $favoriteProfileImages;
}
Option 1
Assuming that there is no relation between User and Favorite models, get all the PostImage records which have an entry in favorites table for the currently logged in user.
$profileImages = Favorite::where('user_id', auth()->id())
->with([
'favoritable' => fn($query) => $query->where('favoritable_type', ProfileImage::class)
])
->get()
->pluck('favoritable')
->flatten()
->all();
Option 2
Assuming that User hasMany Favorite records - hasMany relationship exists
class User extends Model
{
public function favorites()
{
return $this->hasMany(Favorite::class);
}
// ...rest of the class code
}
Get the results via the User model
$profileImages = User::with([
'favorites' =>
fn($query) => $query->where('favoritable_type', ProfileImage::class)->with('favoritable')
])
->where('id', auth()->id())
->first()
->favorites
->pluck('favoritable')
->flatten()
->all();

Laravel relationship with one-to-one

I have the following users table structure:
id
email
....
status // foreign key from tbl_status
Now in my tbl_status:
id
name
description
Now I would like to create a relationship such that if I have a status of 1 in the users table I would like to get its name. I have tried:
In my User model:
class User extends Model
{
protected $fillable = [
'name', 'email', 'password', 'status'
];
public function userstatus()
{
return $this->hasOne('App\Status', 'id', 'status');
}
}
In the Status model:
class Status extends Model
{
protected $fillable = [
'name', 'description'
];
}
When fetching records via...
return User::with("userstatus")->paginate(10);
...it always returns the status as null even though each user has a default status of 1 and the status table has an ID of 1 with a value.
This relationship is backwards. Placing the status foreign key on the users table creates the following relationships:
User belongs to Status
Status has many Users
However, the question shows a hasOne() relation on the User model for userstatuses(). For this to work, tbl_status will need a user_id field, but this means that a Status can only belong to one User.
Instead, the correct relation for userstatus() on User should be belongsTo():
public function userstatus()
{
return $this->belongsTo(App\Status::class, 'status');
}
Then we can use the proper relations on the User model:
$user = User::with('userstatus')->find(1);
$user->status; // 1 (foreign key ID)
$user->userstatus->name; // "status name"
$user->userstatus->description // "This is the status description."
I think the best way to do it will be to add a user_id column that references the users id column as the foreign key instead of status. That should fix it.

Laravel 5 insert pivot table with attributes

I've been learning laravel for a few days now and I was hoping you guy's could help me.
I have the following table structure:
users
------
id
companies
------
id
company_user
------
company_id
user_id
owner
My User and Company models have functions specified like this:
User Model
public function companies() {
return $this->belongsToMany('App\Company', 'company_user', 'company_id', 'user_id')->withPivot('owner');
}
Company Model
public function users() {
return $this->belongsToMany('App\User', 'company_user', 'company_id', 'user_id')->withPivot('owner');
}
For example when I save a company to a user like this:
User::find(1)->companies()->save(\App\Company::find(1));
The pivot table gets filled nicely, but the owner column doesn't get filled.
I can't find many online how to fill this column. Hope you guys can help me?
Thanks in advance!
You can pass additional data as second argument to save():
User::find(1)->companies()->save(\App\Company::find(1), ['owner' => 'foo']);

Laravel base table not found using pivot model

Hi im trying to query my tasks table. A little background information on the tables and how they are related.
Users, create Projects and Tasks, Statuses for projects and tasks can be selected from the status table, users make their own, i plan to have default ones but users may want to create their own.
By default i want to find all the users tasks where the status_name which is held in the statuses table does not equal closed. I decided it would be best to actually create a table called task_status which holds the task_id as well as the status_id. I still want to find the logged in users tasks and then find the status name based on the status_id held in the tasks table, which can be referenced in the statuses table. I then want to only display the any records not equal to closed but the first part which is explained below is trickier than first anticipated.
My table structures can be found below:
Table structure
Users
id | username | email
Tasks
id | user_id | client_id | project_id | status_id | task_name | task_brief
Statuses
id | status_name
Projects
id | user_id | client_id | status_id | type_id | project_name | project_brief
task_status
id | user_id | task_id | status_id
I'm trying to query my db simply first so that I can be sure that the data returned is correct. So I've changed my query to the below:
$user = User::with(array('tasks', 'task.status', 'tasks.taskstatus',
'tasks.clients'))->find(Auth::user()->id);
and I'm trying to return as follows (please bear in mind I also want to query the status table so that I am able to return the name of the status):
#foreach($user->tasks as $task)
{{ $task->task_name }}
#if(!is_null($task->clients))
{{ $task->clients->client_code }}
#endif
#if(!is_null($task->taskstatus))
{{ $task->taskstatus->status_name }}
#endif
#endforeach
My models:
Task.php
public function status(){
return $this->hasOne('Status', 'status_id');
}
public function taskstatus() {
return $this->hasMany('TaskStatus', 'status_id');
}
Status.php
public function tasks()
{
return $this->hasMany('Task');
}
public function taskstatus()
{
return $this->hasMany('TaskStatus', 'status_id');
}
TaskStatus.php
public function tasks()
{
return $this->hasMany('Task', 'task_id');
}
public function status() {
return $this->belongsTo('Status', 'status_id')
}
However using the above returns the following error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'imanage.task_statuses' doesn't exist (SQL: select * from `task_statuses`
where `task_statuses`.`status_id` in (?, ?, ?, ?, ?, ?, ?))
(Bindings: array ( 0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6, 6 => 7, ))
I'm sure that its my relationships that are defined incorrectly but I am not sure how to correct these.Can anyone help?
You can also try this code:
$user = User::whereHas('task.status', function($q)
{
$q->where('status', '!=', 'close');
})
->with('task', 'task.clients')
->where('id', Auth::user()->id)
->first();
Check the eloquent docs on querying relationships.
also remember DO NOT ECHO VIEW, return the view instead.
The error seems related to the fact that Laravel (well, actually Eloquent) is getting the wrong table name: below you have task_statuses instead of task_status. Remember that Eloquent will attempt to pluralize named models to get the table name.
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'imanage.task_statuses' doesn't exist
So either rename your table to match Laravel expectations, or in your model specify a custom table name:
class TaskStatus extends Eloquent {
protected $table = 'task_status';
...
Additionally, this part of your code is unclear to me:
Task.php
public function status(){
return $this->hasOne('Status', 'status_id');
}
public function taskstatus() {
return $this->hasMany('TaskStatus', 'status_id');
}
Does your Task have one status, or does it have many statuses?

Adding a HABTM as a registration in CakePHP

I have Users and Courses.
I have a users table, and a courses table.
I also have a course_memberships table with id |
course_id | user_id
I have the appropriate hasmany relationship
for courses and users to relate to CourseMembership
But I have no idea how to create that relationship using a button on the front end. Something like a public function register() on the Courses controller that would put the Auth User ID in the user_id field, and the course id in the course_id field to form the relationship.
I know it was a wall of text, but I figured a description of the issue may be more helpful than an endless scroll of code.
Can anyone help?
You should create a method to save to the CourseMembership model within the Courses Controller. Something like this would work.
public function register($course_id){
$user_id = $this->Auth->user('id');
$data = array(
course_id => $course_id,
user_id => $user_id;
);
if($this->Courses->CourseMembership->save($data)){
$this->Session->setFlash('Registered');
$this->redirect($this->referer());
}
else{
$this->Session->setFlash('Could not register');
$this->redirect($this->referer());
}
}
This way, when people go to /Courses/register/1, it would register them for the course with the ID of 1.
Then when you do a find on the User, the data would be in $user['CourseMembership']

Categories