I'm trying to delete a record in Doctrine, but I don't know why it's not deleting.
Here is my Code:
function del_user($id)
{
$single_user = $entityManager->find('Users', $id);
$entityManager->remove($single_user);
$entityManager->flush();
}
Plus: How can I echo query to see what going on here?
This is an old question and doesn't seem to have an answer yet. For reference I am leaving that here for more reference. Also you can check the doctrine documentation
To delete a record, you need to ( assuming you are in your controller ):
// get EntityManager
$em = $this->getDoctrine()->getManager();
// Get a reference to the entity ( will not generate a query )
$user = $em->getReference('ProjectBundle:User', $id);
// OR you can get the entity itself ( will generate a query )
// $user = $em->getRepository('ProjectBundle:User')->find($id);
// Remove it and flush
$em->remove($user);
$em->flush();
Using the first method of getting a reference is usually better if you just want to delete the entity without checking first whether it exists or not, because it will not query the DB and will only create a proxy object that you can use to delete your entity.
If you want to make sure that this ID corresponds to a valid entity first, then the second method is better because it will query the DB for your entity before trying to delete it.
For my understanding if you need to delete a record in doctrine that have a doctrine relationship eg. OneToMany, ManyToMany and association cannot be easy deleted until you set the field that reference to another relation equal to null.
......
you can use this for non relation doctrine
$entityManager=$this->getDoctrine()->getManager();
$single_user=$this->getDoctrine()->getRepository(User::class)->findOneBy(['id'=>$id]);
$entityManager->remove($single_user);
$entityManager->flush();
but for relation doctrine set the field that reference to another relation to null
$entityManager=$this->getDoctrine()->getManager();
$single_user=$this->getDoctrine()->getRepository(User::class)->findOneBy(['id'=>$id]);
{# assume you have field that reference #}
$single_user->setFieldData(null);
$entityManager->remove($single_user);
$entityManager->flush();
do you check your entity as the good comment annotation ?
cascade={"persist", "remove"}, orphanRemoval=true
In a Silex route I do like this, in case it helps someone:
$app->get('/db/order/delete', function (Request $request) use ($app) {
...
$id = $request->query->get('id');
$em = $app['orm.em']; //or wherever your EntityManager is
$order = $em->find("\App\Entity\Orders",$id); //your Entity
if($order){
try{
$em->remove($order);
$em->flush();
}
catch( Exception $e )
{
return new Response( $e->getMessage(), 500 );
}
return new Response( "Success deleting order " . $order->getId(), 200 );
}else{
return new Response("Order Not Found", 500);
}
}
You first need repository.
$entityManager->getRepository('Users')->find($id);
instead of
$single_user = $entityManager->find('Users', $id);
'Users' String is the name of the Users repository in doctrine ( depends if you are using Symfony , Zend . . etc ).
First, You may need to check if 'Users' is your fully qualified class name. If not check, and update it to your class name with the namespace info.
Make sure the object returned by find() is not null or not false and is an instance of your entity class before calling EM's remove().
Regarding your other question, instead of making doctrine return SQL's I just use my database (MySQL) to log all queries (since its just development environment).
try a var_dump() of your $single_user. If it is "null", it doens't exist ?
Also check if "Users" is a valid Entity name (no namespace?), and does the $id reference the PK of the user?
If you want to see the queries that are executed check your mysql/sql/... log or look into Doctrine\DBAL\Logging\EchoSQLLogger
Related
I am writing a Symfony3 appusing Doctrine ORM.
SO what i am trying to do is to find if a given email address exists in a table (every email is unique). so i have a user repository with some attributes I can easily persist data to the db but failing to retrive data.
/**
* #param $email
*/
public function findUserByEmail($email)
{
$user = $this->getDoctrine()
->getRepository('TestBundle:TestUser')
->find($email);
if (!$user) {
echo 'Error';die();
}
}
I know the var passed to the function contains a email string, but what i get in return is error and when i var_dump $user before the if statment i get null.
I followed the Symfony docs
Your User probably has a separate primary key field. the find() method on a repo only retrieves by primary key.
Repositories use __call to dynamically process findBy* and findOneBy* methods, so you could call it like this:
$repo = $this->getDoctrine()->getRepository('TestBundle:TestUser');
// magic find method
$user = $repo->findOneByEmail($email);
// explicit find method
$user = $repo->findOneBy(['email' => $email]);
// custom QueryBuilder
$user = $repo->createQueryBuilder('user')
->where('user.email = :email')
->setParameter('email', $email)
->getQuery()
->getSingleResult();
BTW: If you are validating this for a submitted form, there is a contraint that does this check for you: UniqueEntity
I think the problem is because you forgot to call getManager().
So the code would be:
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('TestBundle:TestUser')->findOneBy(['email' => $email]);
Hope it would help you!
I've set up a log in process where a verification code is generated, and when successful, is then removed. However, i want to make sure that if there's multiple verification codes for the same user, upon log in success, delete all records for that user.
Here's my code
if ($model->validate() && $model->login()) {
//delete this verification code
$verificationCode->delete();
//delete all existing codes for user_id
VerificationCode::model()->deleteAll('user_id',$user->id);
Yii::app()->user->setReturnUrl(array('/system/admin/'));
$this->redirect(Yii::app()->user->returnUrl);
}
However, this seems to just delete all the records, regardless on different user_id's in table. Can anyone see where I'm going wrong?
If you want to delete record with specified attributes, the cleanest way for this is to use deleteAllByAttributes():
VerificationCode::model()->deleteAllByAttributes(['user_id' => $user->id]);
Seems you call the function delete() in wrong way ... try passing value this way
VerificationCode::model()->deleteAll('user_id = :user_id', array(':user_id' => $user->id));
For Yii2, the documented way is to use the function deleteAll().
I normally pass the arguments as an array, like so:
VerificationCode::deleteAll(['user_id' => $user->id]);
Also, you can use the afterDelete method, to make sure that everytime or everywhere someone deletes one verificationCode, your application will also delete every userVerificationCode. Put this in your verificationCode model class:
protected function afterDelete()
{
parent::afterDelete();
VerificationCode::model()->deleteAll('user_id = :user:id',[':user_id' =>$this->user_id]);
//... any other logic here
}
You can use below method for deleting all user_id entry from database:
$criteria = new CDbCriteria;
// secure way for add a new condition
$criteria->condition = "user_id = :user_id ";
$criteria->params[":user_id"] = $user->id;
// remove user related all entry from database
$model = VerificationCode::model()->deleteAll($criteria);
or you can use another method directly in controller action
VerificationCode::model()->deleteAll("user_id= :user_id", [":user_id"
=>$user->id]);
use below method for redirecting a URL
$this->c()->redirect(Yii::app()->createUrl('/system/admin/'));
I need to update the Client table's budget column after inserting a new Budget into the database, but it doesn't. This is how I am doing inside of BudgetController::addAction():
if ($form->isValid()) {
$manager->persist($form->getData());
$manager->flush();
$Client = $manager->getReference('PanelBundle:Client', $form['client_id']->getData()->getId());
$Client->setBudget($manager->getRepository('PanelBundle:Budget')->getLastId());
$this->addFlash('success', 'Novo orçamento adicionado');
return $this->redirect($this->generateUrl('panel_budgets'));
}
The $Client declaration returns the Client name successfully, but the line where it sets the setBudget() seem not to work. I don't know how to make an update like this. I need it to update after inserting into Budget according to the selected Client id in Budget form.
Client and Budget are related to oneToMany and manyToOne, respectively, am I missing something because of this relationship?
If the Budget entity is a ManyToOne association of the Client, then you should be using ->addBudget() instead of a setter. It's also probably better to do a ->find() for the Client entity instead of a ->getReference(). If you really want to save the extra trip to the database, use the setter on the Budget entity instead to set the $client proxy created by the ->getReference(), i.e. $budget->setClient($client);. But it's not that expensive to find the Client and it ensures that the Client of that id exists. It would then also be a good idea to flush the manager again, just to make sure things are wrapped up cleanly, instead of assuming it will all happen without interruption as the kernel terminates. A complete rendition of your controller and action should look something like this:
namespace PanelBundle\Controller;
use PanelBundle\Entity\Budget;
use PanelBundle\Form\Type\BudgetType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class BudgetController extends Controller
{
public function addAction(Request $request)
{
$budget = new Budget();
$budgetForm = $this->createForm(new BudgetType(), $budget);
$budgetForm->handleRequest($request);
if ($budgetForm->isValid()) {
$manager = $this->getDoctrine()->getManager();
$manager->persist($budget);
$manager->flush();
$client = $manager->getRepository('PanelBundle:Client')
->find($budgetForm->get('client_id')->getData())
;
$client->addBudget($budget);
$manager->flush();
$this->addFlash('success', 'Novo orçamento adicionado');
return $this->redirect($this->generateUrl('panel_budgets'));
}
return $this->render(
'PanelBundle:Budget:add.html.twig',
array(
'budgetForm' => $budgetForm->createView(),
)
);
}
}
I'm new with Symfony2 and i would like to know whether there is a way to use the "findBy" with a param which is present only in a mapped entity.
This is my snippet controller:
$prods = $em->getRepository('EcommerceProductBundle:ProductData')
->findBy(array(
'product_id'=>46
));
It works good but if i try to add another element to the array, which is present in a mapped entity, it get (rightly) this error
Unrecognized field: ProductImage.is_visible
What i would like to do, is just to know wehether i can use the "filterBy" with a mapped element of the entity ProductData.
I'm in wrong but this is my idea:
->findBy(array(
'product_id'=>46,
'ProductImage.is_visible'=>1
));
Not possible as far as i know. Just add this custom method to your repository:
public function findByIdAndVisibleImage($id)
{
return $this->createQueryBuilder('product')
->lefJoin("product.image","i")
->where("product.product_id = :id")
->andWhere("i.is_visible = 1")
->setParameter("id", $id)
->getQuery()
->getSingleResult();
}
You can't do that, you need to write a custom method in the repository with a join clause.
The findBy method just add a where clause on the criteria.
In Doctrine2 using some thing like:
$user = array('username' => 'example', 'passsword' => 'changeme');
$conn->insert('users', $user);
How would I then get the last ID of the user I just inserted? If it is not possible to do this then how do you gen a id so that you can the following:
$id = //something here.
$user = array('username' => 'example', 'passsword' => 'changeme', 'id' => $id);
$conn->insert('users', $user);
If you are using the ORM
$em->persist($object);
$em->flush();
$object->getId();
if you are using the DBAL:
$conn->lastInsertId();
http://www.doctrine-project.org/api/dbal/2.5/class-Doctrine.DBAL.Connection.html#_lastInsertId
One can use the Doctrine\DBAL\Connection::lastInsertId() method.
It can be used with native queries as well as manually written inserts.
Example case:
$query = 'INSERT INTO blabla...';
$connection->executeUpdate($query, $params);
var_dump($connection->lastInsertId());
If using the ORM, you can obtain an instance of the connection from the entity manager:
$connection = $em->getConnection();
Note:
Aside from the technical details, I agree with #Layke for using an entity for your specific case.
$conn->lastInsertId();will get you the last inserted ID when only using Doctrine's DBAL (sans ORM).
Providing that your Entity which are you are trying to set has
/**
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
Then when you persist your object, the entity manager will populate the Entity which you are trying to persist with the ID.
Some caveats however, is that you can't do this with composite keys post obviously, and you obviously have to flush all Entities. So if you detach an Entity which has an association to the persisted entity that you are trying to get the ID for, then you won't be able to retrieve the ID.
Aside from that Flask's answer is bang on.
$em->persist($object);
$em->flush();
$object->getId();