Updating a friend list in my database - mysql

I have been storing the friend list using the following database structure:
User Id | Friend Id
My problem is that I have an interface that lets them add/delete users from the friend list and the friend list should get saved upon hit.
So would it make sense that I delete all the friends for that user Id and then repopulate the database with the saved friend list ? Sounds a bit counterproductive because if a user adds just one more user, it would be deleting all the friends and re-adding them all.

You can delete all and then repopulate or you can store the initial state of the list of friends, then compare with the final list after user edit.
I recommend you use this function array_diff($array1, $array2), doing something like:
$initial_list = array (1,2,3,4,5);
$list_after_edit = array (1,2,5,6);
$all_new_items = array_diff($list_after_edit,$initial_list);
foreach ($all_new_items as $item) {
// Add to database this item
}
$all_deleted_items = array_diff($initial_list,$list_after_edit);
// Execute this query:
$query = 'DELETE FROM table WHERE `User Id` = <some ID> AND `Friend Id` in (' . implode(',',$all_deleted_items) . ')';

Related

Laravel 8 collection filter with raw DB query

I have a User model and a users table like so.
Besides that I have a verification_reminders table.
first_reminder and second_reminder fields are nullable.
When a user signs up a record is inserted in the users table with a null email_verified_at field. When they verify their email the field is populated with a timestamp. If they take too long without verifying their email, a reminder is send out to them. As the reminder is being sent out for the first time a record is inserted in the verification_reminders table and the first_reminder is populated with a timestamp.
If they still do not verify a last final reminder is sent out and the second_reminder field populated with a timestamp.
I need to run a query to select users who have null email_verified_at in the users table.
Next I need to separate the users into two lists/collections:
Not reminded users who have null email_verified_at in the users table but no record of their users_id in the verification_reminders table.
First reminded users who have null email_verified_at in the users table and with a record of their user_id in the verification_reminders table with a populated first_reminder field but a null second_reminder
My attempt at this
$users = User::whereNull('email_verified_at')->get();
$users_not_reminded = collect($users)->filter(function($item){
$reminded = DB::table('verification_reminders')->where('user_id', $item->id)->whereNull('first_reminder')->whereNull('second_reminder');
if($reminded->isEmpty()){
return $item;
}
});
I'm able to retrieve the $users but $users_not_reminded throws an error Call to undefined method Illuminate\Database\Query\Builder::isEmpty()
I've not even started on $users_first_reminded yet. I'm not sure how to proceed because this query is a bit too complicated for me. I'm hoping someone with experience could point out the cleaner way for me to achieve this.
Thank you. I'm using laravel 8 by the way.
You have not called first() or get() in db query
$reminded = DB::table('verification_reminders')
->where('user_id', $item->id)
->whereNull('first_reminder')
->whereNull('second_reminder');
so instead of above you should call first() or get()
$reminded = DB::table('verification_reminders')
->where('user_id', $item->id)
->whereNull('first_reminder')
->whereNull('second_reminder')
->first();
I suggest you to Create model for verification_reminders table then add relationship in user Model
public function verificationReminder(){
return $this->hasOne(VerificationReminder::class);
}
then you can do
$users = User::whereNull('email_verified_at')
->with('verificationReminder')
->whereHas('verificationReminder',function ($query){
$query->whereNull('first_reminder')
->whereNull('second_reminder');
}) ->get();

Doctrine and Mysql data migration during table structure change

There is Entities User and Company. Company has user_id.
Now table structure changes and next one user can represent many companies and vice versa (Many to Many eg One to Many - Many to One). This introduces CompanyRepresentative Entity in the middle with fields user_id, company_id and role. Companies user_id will be dropped with that change.
How to make data migration script for that situation? There must be CompanyRepresentative entry for each company present right now that connects same user and company that are connected right now.
Environment is symfony 4 application with Doctrine and Mysql.
Doctrine migrations have functions preUp and postUp. In preUp it is possible to select all needed data and in postUp this data can be inserted to correct places after database structure changes.
For example
public function preUp(Schema $schema)
{
parent::preUp($schema);
$query = "SELECT id, user_id FROM company";
$data = $this->connection->prepare($query);
$data->execute();
foreach ($data as $row) {
$userId = $row['id'];
$companyId = $row['user_id'];
$this->customSQL[] = "($userId, $companyId)";
}
}
public function up(Schema $schema)
{
//Change the schema
}
public function postUp(Schema $schema)
{
parent::postUp($schema);
$SQL = 'INSERT INTO company_rep (user_id, company_id) VALUES ' . implode(', ', $this->customSQL);
$this->connection->executeQuery($SQL);
}
You have to use DoctrineMigrationBundle to do this. look at the documentation here, you should get away with it.

Symfony 2 Self referencing many to many repository

I have a self referencing many to many relationship on my User entity being they can have many followers or follow many other users.
I am now trying to write a query in the user repository which will determine if a user is following another user.
I tried to write the query directy on user_relations (the mapping table) but it would not let me as it not related to the user entity.
So I tried:
$query = $this->createQueryBuilder('u')
->select('count(u.id)')
->innerJoin('u.following', 'r')
->where('u.id = :userID')
->where('r.from_id = :followingID')
->setParameter('userID', $userId)
->setParameter('followingID', $followingId)
Which results in an error stating the user entity does not have a field named from_uid.
How the hell can I correctly achieve this?
You can use MEMBER OF doctrine keyword
$query = $em->createQuery('SELECT u.id FROM User u WHERE :followingID MEMBER OF u.following');
$query->setParameter('followingID', $followingId);
$ids = $query->getResult();

Update multitables using one form in symfony+Doctrine

Hi I am building a registration system in symfony. It has three models -User, jobSeeker and employer. Jobseeker and employer inherit user.
There are 4 steps in the jobseeker registration process, in the first step users have to enter their login detail & it will be added to the user table. In the next steps user has to enter his personal details, it will be added to the jobseeker table.
I want to update the user table and jobseeker table using one form, how can I do it??
(For example address and tp number are in the user table, but it will be updated in the second step)
Thankyou for ur replies
It is working
what I did was
In my dao class
public function updateStep($step,$address, $phone, $id)
{
Doctrine_Query::create()
->update('User u')
->set('u.step', '?', $step)
->set('u.address', '?', $address)
->set('u.telephone', '?', $phone)
->where('u.user_id = ?', $id)
->execute();
}
In the form class
public function updateStep()
{
$step = $this->getValue('step');
$phone = $this->getValue('phone');
$address = $this ->getValue('address');
$id = $this->getValue('user_id');
$updateStep = $this->getUserManagementService()->updateStep($step, $address, $phone, $id);
return $updateStep;
}
Finally in the registration action
$this->form->updateStep();
It is working but am I doing it in the right way or is there any easier way exist?
Simply ... you can create new object from User and new object from jobseeker in first step and put this object in session and in step two retrieve this object from session and update it with data
and in last step save those two objects.

What's the best way to save a one-to-many relationship in Linq2Sql?

I'm trying to figure out the best way to save a simple one-to-many relationship in Linq2Sql.
Lets assume we have the following POCO model (pseduo code btw):
Person has zero to many Vechicles.
class Person
{
IList<Vehicle> Vehicle;
}
class Vehicle
{
string Name;
string Colour;
}
Now, when i save a Person, i pass that poco object to the repository code (which happens to be L2S). I can save the person object fine. I usually do this.
using (Db db = new Db())
{
var newPerson = db.People.SingleOrDefault(p => p.Id == person.Id) ?? new SqlContext.Person();
// Left to right stuff.
newPerson.Name = person.Name;
newPerson.Age = person.Age;
if (newPerson.Id <= 0)
db.People.InsertOnSubmit(newPerson);
db.SubmitChanges();
}
i'm not sure where and how i should handle the list of vehicles the person might have? any suggestions?
using (Db db = new Db())
{
var newPerson = db.People.SingleOrDefault(p => p.Id == person.Id) ?? new SqlContext.Person();
// Left to right stuff.
newPerson.Name = person.Name;
newPerson.Age = person.Age;
// add vehicles.
Vehicle firstV = new Vehicle();
firstV.Name = "some name";
firstV.Person = newPerson; // need to do this to set the person Id on the vehicle.
newPerson.Vehicle.Add(firstV);
// now when you save the Person it should save the Vehicle list
// if you set Cascade save update on the list. (not sure how to do that in L2S
if (newPerson.Id <= 0)
db.People.InsertOnSubmit(newPerson);
db.SubmitChanges();
}
Now you may choose to construct the list of vehicles at another level , with the data that's coming from the interface.
But you need to remember that it's not enough to add the Vehicle to the list on the Person object , you also need to set the vehicles Person property to the person that has the vehicles.
Observation I'm not sure about this but when you do db.People.SingleOrDefault you might be loading the whole People table in memory . That's not something you want to do. Corrected by Slace in the comments.
All you need to do is ensure that there are the appropriate relationships set up within the database.
If your Vehicle table has a PersonId and there is a foreign key between them when you add them to the DBML Linq to SQL will detect that there is a relationship between them and create a Table<T> representation of the relationship.