web-dev-qa-db-fra.com

Comment mettre à jour des données avec Eloquent sans identifiant Laravel 4

Lorsque je souhaite mettre à jour la base de données FaqTrans, mais que cette base de données possède deux clés primaires (faq_ida et lang) $table->primary(array('lang', 'faq_id'));. je n'ai donc pas besoin d'une colonne id avec auto_increment.

Cependant, lorsque j'utilise le code suivant pour mettre à jour la base de données, le message d'erreur me laisse entendre qu'il n'y a pas de colonne id.

$faq_trans = FaqTrans::where('faq_id','=',$faq_id)->where('lang','=',$lang)->first();
$faq_trans->lang  = Input::get('lang');
$faq_trans->body  = Input::get('body');
$faq_trans->title = Input::get('title');
$faq_trans->save();

message d'erreur

SQLSTATE [42S22]: Colonne introuvable: 1054 La colonne inconnue "id" dans "clause Where" (SQL: update FAQtrans set body =?, updated_at =? Où id est null) (Liaisons: array (0 => 'adfadaaadfadaa', 1 => '2013-07-04 11:12:42',))

et quand j'ai ajouté une colonne id, le code fonctionne bien ...

puis-je mettre à jour la base de données sans colonne d'ID?

13
Eugene Wang

Laravel/Eloquent ne prend pas en charge les clés primaires composites.

Lorsque vous vérifiez la classe Eloquent Model, vous pouvez voir que la clé primaire ne peut être qu'une chaîne, utilisée pour créer la clause WHERE.

6
Nico Kaag

Écrivez cette ligne dans votre modèle

public $primaryKey = '_id';

Où _id est votre clé primaire manuelle

28
Nishchit Dhanani

Assez simple:

FaqTrans::where(
            [
                'faq_id' => $faq_id,
                'lang' => $lang
            ]
        )->update(
            [
                'body' => $body,
                'title' => $title
            ]
        );
5
Alex

Pour ceux qui trébuchent dans le futur sur cette question (comme je l’ai fait), voici une solution de contournement de Nice pour une clé primaire composite dans Eloquent.

Cela va au sommet de votre classe de modèle:

protected $primaryKey = array('key1', 'key2');

Ensuite, vous remplacez la méthode save() sur votre modèle par ceci:

public function save(array $options = array())
{
    if(!is_array($this->getKeyName()))
        return parent::save($options);

    // Fire Event for others to hook
    if($this->fireModelEvent('saving') === false)
        return false;

    // Prepare query for inserting or updating
    $query = $this->newQueryWithoutScopes();

    // Perform Update
    if ($this->exists) {
        if (count($this->getDirty()) > 0) {
            // Fire Event for others to hook
            if ($this->fireModelEvent('updating') === false)
                return false;

            // Touch the timestamps
            if ($this->timestamps)
                $this->updateTimestamps();

            //
            // START FIX
            //

            // Convert primary key into an array if it's a single value
            $primary = (count($this->getKeyName()) > 1) ? $this->getKeyName() : [$this->getKeyName()];

            // Fetch the primary key(s) values before any changes
            $unique = array_intersect_key($this->original, array_flip($primary));

            // Fetch the primary key(s) values after any changes
            $unique = !empty($unique) ? $unique : array_intersect_key($this->getAttributes(), array_flip($primary));

            // Fetch the element of the array if the array contains only a single element
            $unique = (count($unique) <> 1) ? $unique : reset($unique);

            // Apply SQL logic
            $query->where($unique);

            //
            // END FIX
            //

            // Update the records
            $query->update($this->getDirty());

            // Fire an event for hooking into
            $this->fireModelEvent('updated', false);
        }

    // Perform Insert
    } else {
        // Fire an event for hooking into
        if ($this->fireModelEvent('creating') === false)
            return false;

        // Touch the timestamps
        if ($this->timestamps)
            $this->updateTimestamps();

        // Retrieve the attributes
        $attributes = $this->attributes;

        if ($this->incrementing && !is_array($this->getKeyName()))
            $this->insertAndSetId($query, $attributes);
        else
            $query->insert($attributes);

        // Set exists to true in case someone tries to update it during an event
        $this->exists = true;

        // Fire an event for hooking into
        $this->fireModelEvent('created', false);
    }

    // Fires an event
    $this->fireModelEvent('saved', false);

    // Sync
    $this->original = $this->attributes;

    // Touches all relations
    if (array_get($options, 'touch', true))
        $this->touchOwners();

    return true;
}

Source originale: https://github.com/laravel/framework/issues/5517#issuecomment-52996610

Mise à jour 2016-05-03

Ma nouvelle manière préférée de faire ceci:

Comment puis-je mettre des clés composites dans les modèles dans Laravel 5?

5
mopo922

Allez dans votre modèle FaqTrans et ajoutez ceci.

public $key = 'faq_id';

Cela devrait le faire, en supposant que faq_id est plus important que la lang

1
Ironwind