简体   繁体   中英

How to retrieve the related entities for an entity?

I'm designing a messaging API, and I have set a PUT /message method.

The payload consists of an array containing three fields: message , sender and receiver – the first one is the message itself and the following fields are each a representation of an User. The payload can be something like:

{
    "message": "Hi!",
    "sender": { "id": 1 },
    "receiver": { "id", 2 }
}

By using the JMSSerializerBundle , I could successfully translate the payload into a Message entity and its users into their respective User entities. This is the Message entity:

/**
 * @ORM\Entity
 */
class Message
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumn(name="sender", referencedColumnName="id", nullable=false)
     */
    protected $sender;

    /**
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumn(name="receiver", referencedColumnName="id", nullable=false)
     */
    protected $receiver;
}

What I want to do is to be able to receive the payload and then persist it in the database. No more, no less. The controller is as follows:

/**
 * @Configuration\Method("PUT")
 * @Configuration\Route("/message")
 */
public function putMessageAction(Request $request)
{
    /** @var Message $message */
    $message = $this
        ->getJMSSerializer()
        ->deserialize($request->getContent(), 'Message', 'json');

    // at this point I want both sender and receiver to be two database users

    if ($message->getSender()->getId() === $message->getReceiver()->getId()) {
        throw new \Exception("A message's sender and receiver cannot be the same people.");
    }

    $em = $this->getDoctrine()->getManager();
    $em->persist($message);
    $em->flush();

    return JsonResponse::create([
        'message' => 'Message successfully received.'
    ], 200);
}

I have abbreviated the namespaces just to focus on the problem itself. Nothing to worry about this. :)

As requested, here is a non-JMSSerializer based solution. Not tested.

// Turn json payload into an array
$data = json_decode($request->getContent(),true);

// Load references to users, no need to load the entire object in
$em = $this->getDoctrine()->getManager();
$sender   = $em->getReference('User',$data['sender'];
$receiver = $em->getReference('User',$data['receiver'];

// Build and persist the message
$message = new Message(); // or new Message($sender,$receiver,$data['message']);
$message->setSender($sender);
$message->setReceiver($receiver);
$message->setMessage($data['message']);

$em->persist($message);
$em->flush();

It's also possible to do this sort of mapping with forms.

And while it's a bit off topic, if you are trying to make a RESTlike interface then POST is probably a better solution for creating a new resource. And returning a 201 status code along with a redirection link to the new resource is also more typical.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM