0

I'm using the mongodb/laravel-mongodb package in a Laravel project and running into an issue with documents that have both _id and id fields.

For example, a document in my collection looks like this:

{
  "_id": ObjectId("68de3600f72aacb41204351d"),
  "id": "custom123",
  "name": "Example"
}

When I try to update it using Eloquent:

$doc = CustomHtml::where('_id', '68de3600f72aacb41204351d')->first();
$doc->name = "Updated Example";
$doc->save();

The update fails or doesn't behave as expected.

I suspect the issue comes from the package automatically mapping the _id field to the Eloquent id property, which conflicts with my custom id.

What I want:

Keep the _id as the MongoDB ObjectId.

Keep my id as a separate custom identifier.

Be able to update the document using Eloquent without removing either field.

Question: Is there a way to disable the automatic _id ↔ id mapping in mongodb/laravel-mongodb so that Eloquent can work with documents containing both _id and id fields?

3
  • 2
    As the other user already answered, the issue is the clash between _id and id. My recommendation is to scrap id, as you are misusing it (relative to how the FRAMEWORK works). If you want to have your own columns and stuff like that in a database, do it, but know that the framework is adpated to work in a way, and you are completely going over it not caring about it, so you will have these issues and they are very annoying. The easiest solution would be to rename id to something that is relevant, what is id if you already have _id? simply rename id to something else and done! Commented Oct 2 at 11:52
  • We cannot rename it, since id is already used in many places across our system and changing it would break a lot of existing functionality. With jenssegers/mongodb this setup worked perfectly fine — _id was the Mongo ObjectId and id was our own custom unique identifier. That’s why this new enforced mapping behavior is causing problems for us. It would be very helpful if there was an option to disable the _id <-> id mapping, so projects like ours could continue working without major refactoring. Commented Oct 2 at 17:12
  • Sorry to hear. Your problem then seems way deeper and complex than it is. Why? Because Laravel uses id as the main id, but mongo uses _id. This is mostly a driver issue, as you are describing, because you had no issues with another package. Still, Laravel will always treat id as the main id, so the other driver was wrong or something like that. Either way, to try to help you, I would do what the answer to your question says. Is chaging $primaryKey to _id not working? Check how the driver works behind sceens so you check why is not using $primaryKey correctly. Maybe it is a bug Commented Oct 3 at 16:39

1 Answer 1

3

The problem comes from how Eloquent (and the mongodb/laravel-mongodb package) internally handles _id.

In Eloquent, the primary key column is always mapped to the model’s $primaryKey (defaults to id). The mongodb/laravel-mongodb driver maps Mongo’s _id field into this property. That means:

  • _id in the database → $model->id in Eloquent.

  • If you also have your own id field, it clashes with this behavior because Eloquent thinks it’s dealing with the primary key.

That’s why updates aren’t behaving correctly, Eloquent is confused between your custom "id" and Mongo’s _id.

You need to tell your model not to use the id alias for _id and instead explicitly work with _id.

In your model (CustomHtml), do this:

use Jenssegers\Mongodb\Eloquent\Model;

class CustomHtml extends Model
{
    protected $collection = 'custom_htmls';

    protected $primaryKey = '_id'; // explicitly use _id as the primary key

    protected $fillable = ['id', 'name']; // 'id' here now is just another attribute
}

Now when you query:

$doc = CustomHtml::where('_id', new \MongoDB\BSON\ObjectId("68de3600f72aacb41204351d"))->first();
$doc->name = "Updated Example";
$doc->save();
Sign up to request clarification or add additional context in comments.

2 Comments

The update works perfectly, but when I try to insert a new document and set $model->id = 'mg97t3jkuwuv', the value is saved under _id instead, and the id field itself disappears from the document.
You need to avoid using the magic id property, and instead treat your custom "id" field like a normal attribute. $doc = new CustomHtml(); $doc->id = 'mg97t3jkuwuv'; // goes to _id $doc['id'] = 'mg97t3jkuwuv'; // goes to your custom "id" field $doc->name = 'Example'; $doc->save();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.