add model relationship without save - php

I have the next relationship User hasMany Contacts.
In normal situation is use $user->contacts()->save($contact) to add and save a contact to the user, but I need to associate contacts to users without save the models (User and Contacts).
edit:
I need to build a plant that receives one of such methods and return an XML a collection of templates, only in some of these models will be stored at postiriori.

You can use the associate on your model with belongsTo.
$contact= Contact::find(10);
$user->account()->associate($contact);
$user->save(); // You do need to update your user
Source: http://laravel.com/docs/eloquent

If you know the UserID, just create a new Contact; and make sure to have the correct User ID in the user_id column. Don't even have to touch the User.

Related

Laravel insert into many to many relation table [duplicate]

A simple and straight one:
How can I attach or detach new records when using a Laravel hasManyThrough relation the Laravel way?
Model retrieving is obvious, from the docs here.
EDIT: In other words, is there a Laravelish way of doing the following smarter (model names taken from docs)?
$user = $country->users()->first;
$post->user_id = $user->id;
$post->save();
Thanks in advance.
hasManyThrough() requires an existing intermediate relationship. In the docs example, User is the intermediate relationship. Directly attaching a Post to a Country is not possible because it doesn't know which User owns it. You need to first attach it to the User.
https://laravel.com/api/5.8/Illuminate/Database/Eloquent/Relations/HasManyThrough.html
Yes, but you have to specify all the params.
firstOrNew
// (Doesn't persist to DB, you have to manually call the save method later on the created model)
updateOrCreate
// (Persists to DB)
rawUpdate
// (Persists to DB, not recommended)
push is supposed to work too, according to the docs.
On a 1:M relationship, there's the save method available out of the box. That's because the only field Laravel has to fill in is the foreign key.
For example, Let's say you've got a Parent and Child models. When you call
$parent->children()->save(new Child(...));
Laravel fills in the foreign key and persists the model
If we had a GrandParent model as well, and we tried to save a child through a HasManyThrough relationship:
$grandparent->grandchildren()
Laravel would not only have to fill in for the Parent foreign key, but maybe even create a new Parent model as well since we're not sure it exists. That's why there's not a save method implemented.
Therefore, you can make something like
$grandparent->grandchildren()->firstOrNew(['parent_id' => $parent_id])->save();
// Or
$grandparent->grandchildren()->updateOrCreate(['parent_id' => $parent_id]);
You need a valid key too or else you'll get a SQL constraint violation.

Laravel many to many with a pivot relationship.

User
uid
Provider
pid
Resolution
rid
ProviderResolution
prid
pid
rid
active
ProviderResolutionUser
prid
uid
class Provider extends Model {
public function resolutions()
{
return $this->belongsToMany('App\Models\Resolution')->withPivot('active')->withTimestamps();
}
}
class Resolution extends Model {
public function providers()
{
return $this->belongsToMany('App\Models\Provider')->withPivot('active')->withTimestamps();
}
}
class User extends Model
{
}
Trying to create a Eloquent relationship with this.
I'm trying to figure out how to fit user into this model. It seems like it's suppose to belongsToMany. Do I need to create a class that represents the pivot?
Then from the case of the User how would I query a list resolutions?
You didn't ask but I personally think it's a lot easier to let the primary key of each table be 'id.' Also, in the case of ProviderResolution, unless you have a specific case for it, you don't need (and shouldn't use) 'prid' at all. Just 'pid', 'rid' and 'active' should be sufficient. The 'pid' and 'rid' make the composite primary key on their own. If you add yet another key ('prid'), then there will be a three-key composite which will technically enable you to have duplicates with your other two primary keys. Yuck. Example: PRID:1, PID:1, RID:1, then PRID:2, PID:1, RID:1. Now you have duplicates but your record is technically still unique because of the PRID key. But, maybe you want it this way for some reason?
For the answer I'm going to assume you are using Laravel 5.4+.
So first off, you don't need a class for the pivot. And secondly, you are currently trying to create a relationship between the user and the existing pivot table between Provider and Resolution by creating a table called 'provider_resolution_user'. If you want to query resolutions for a user, just use the relationship methods which gives you access to the attributes on the pivot table and the related models/tables.
First, setup the 'hasMany' relationships in both classes: Users and Resolutions (Providers already has a relationship to Resolutions, so you can use that relationship if you want to see the related Provider.) Then you'll need a pivot table called 'resolution_user'. Put the 'uid' and the 'rid' in the table. Make the relationships to the corresponding foreign key fields to their parent tables.
Now you can access the relationship directly like:
$user->resolutions->rid (or whatever the attribute is you want)
The previous example assumes you have already created a way to insert records into the pivot table (resolution_user) that relate the user and the resolution together.
If you want to access one of the attributes on the pivot table, 'pivot' creates an object instance with it's own attributes (from the table). You can access it like this:
$user->resolutions->pivot->active;
Of course, these methods are chainable so if you just wanted to see the active resolutions, you could also add a ->where statement.
Hope that helps and wasn't too muddy. I'm happy to clarify any points if need be.
EDITED ANSWER:
Because what you want to do is to disable a row in the provider_resolution table and have that reflect on the correct user, then just create a relationship in both the User model and the Resolution model. So when you disable a row in provider_resolution (pid, rid, active), you can lookup the appropriate user to update by using the inverse relationship between resolution and user. This should give you the user that is assigned to that particular resolution/provider combination. If for some reason you do need to find the user based on a unique combination of the TWO: resolution AND provider, then we might need to talk about polymorphic relationships. Let me know.

How to retrieve data from additional columns in a pivot table and also be able to update it in laravel 5.2

I was working on making a group functionality for my website which uses a many to many relationship between groups and users.
My User model looks like this:
public function groups(){
return $this->belongsToMany('App\Group')->withPivot('role')->withTimestamps();
}
My Groups model looks like this:
public function users(){
return $this->belongsToMany('App\User')->withPivot('role')->withTimestamps();
}
So my third column has the name of role which is a string variable and is set to a default of "member" for members of my group and I set it to "admin" for the actual user who creates a new group. But I want the admin to have the option of making multiple members admins as well which would require me to check weather the current current user who sent the request is an admin or not. If he is, then I wanna be able to take his request of making a member an admin which would require me to update the role for that particular "member" to an "admin".
In the laravel documentation it only shows you how to attach and detach data in a pivot table and else where I have only seen methods of retrieving data from the first two columns but how can I do the same for additional columns and also be able to update it using the updateExistingPivot method?
You could access the column simply using pivot e.g :
$user->pivot->role
Take a look at Retrieving Intermediate Table Columns in documentation Eloquent Relationships.
Hope this helps.

Managing a 2 way relationship in CakePHP without retrieving data twice

I am having troubling linking some of my models together. Users have one of three roles:
Student
Lecturer
Admin
Information that is shared between the 3 roles is stored in a User table. When a User wants to change their role they make a role request that must be accepted by Admin.
User has one Student
User has one Lecturer
User has one Admin
User has one RoleRequest
Student belongs to User
Lecturer belongs to User
Admin belongs to User
What I am struggling with is that I cannot find a way of retrieving the data of a user without retrieving their role or their user data twice. If I retrieve the User object with recursive set to 2 I get the user data twice as it is also inside the Lecturer object. If I do the same with the Lecturer object I get the lecturer data twice as it is also inside the User object.
Don't use recursive. Set public $recursive=-1; in your AppModel, then use CakePHP's AMAZING ContainableBehavior to retrieve whatever data you'd like.
If I understood your question correctly, I'm guessing you're not using Contaible.
With that behaviour, you can do something like
$this->User->find('all', array('contain'=>'Lecturer'));
and that will retrieve an array similar to
[User] => array(/*user data*/),
[Lecturer] => array(/*Lecturer data*/)
Just remember to define your models as containable.

Create user roles and profiles in Codeigniter using Ion Auth

I'm using Codeigniter with Ion Auth for user management. I'd like to create two different user roles - one for volunteers and one for organizations. I know that I can use Ion Auth's groups for things like access control, but what would be a good way to add fields to the different user types (for instance - the volunteer user will have a 'languages spoken' field while the organization will have a 'mission' field)? Should I extend the Ion Auth class for each new user type and handle CRUD seperately for each type, or use the 'groups' field and the user id to reference the fields in another table? Any insight as to an approach to this common problem?
I would recommend just adding all the fields you need into the meta table and only updating the ones you need per user group. If you need multiple groups per user check out Ion Auth v2.
I had the same problem before, what I ended up doing was building relation tables to handle different groups with different fields. Then I modified the profile() code a bit, to join the additional relation table according to the user's group settings.
I would start off building a relational database.
example:
**volunteers table**
id
user_id
languages
**organizations table**
id
user_id
mission
Then depending on user group, join the table in profile() function.
Hope this helps!

Categories