2013-07-04 18 views
13

Kiedy chcę zaktualizować bazę danych FaqTrans, ale ten zbiór danych ma dwa klucze podstawowe (faq_ida i język): $table->primary(array('lang', 'faq_id'));. więc nie potrzebuję kolumny id z funkcją auto_increment.Jak zaktualizować dane w Eloquent bez identyfikatora w Laravel 4

Jednak, gdy używam następującego kodu do aktualizacji bazy danych, komunikat o błędzie podpowiada mi, że nie ma kolumny 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(); 

komunikat

SQLSTATE [42S22] Kolumna nie znaleziono: 1054 wiadomo w kolumnie 'id' z 'gdzie punkt' (SQL: zmiana FAQtrans ustawione body =, updated_at = gdzie? id jest zerowy) (Wiązania: tablica (0 => 'adfadaaadfadaa', 1 => '04.07.2013 11:12:42'))

i kiedy dodaje się id kolumna, kod działa poprawnie ...

Czy istnieje sposób aktualizacji bazy danych bez kolumny ID?

+0

pan ustawić klucz podstawowy w modelu –

+0

próbowałem ustawić klucz podstawowy w modelu, ale wydaje się, nie można ustawić dwa klucz podstawowy na raz (kluczu złożonym), jak 'protected $ primaryKey = array ('lang''faq_id'); ' –

+0

Być może będziesz musiał użyć' -> update (array ('column' => 'value')) 'zamiast używać save. –

Odpowiedz

7

Laravel/Eloquent nie obsługuje złożonych kluczy podstawowych.

Po sprawdzeniu klasy Efektywny model można zauważyć, że klucz podstawowy może być tylko łańcuchem, który służy do tworzenia klauzuli WHERE.

1

Przejdź do swojego modelu FaqTrans i dodaj to.

public $key = 'faq_id'; 

To powinno wystarczyć, zakładając faq_id jest ważniejsza niż lang

+0

Myślę, że teraz jest $ primaryKey zgodnie z tym: http://laravel.com/docs/eloquent # basic-usage – ftrotter

27

tą linijkę do swojego modelu

public $primaryKey = '_id';

Gdzie _id to podręcznik podstawowy klucz

4

Całkiem proste:

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

Dla każdego, kto natknie się na to pytanie w przyszłości (tak jak ja), oto ładny sposób na obejście złożonego klucza podstawowego w Eloquent.

To idzie na szczycie swojej klasy model:

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

Następnie należy zastąpić metodę save() modelu z tym:

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; 
} 

Oryginalne źródło: https://github.com/laravel/framework/issues/5517#issuecomment-52996610

aktualizacji 2016-05-03

Mój nowy ulubiony sposób, aby to zrobić:

How I can put composite keys in models in Laravel 5?

-1

Jeśli ktoś ma ten sam problem. Użyłem odpowiedzi Nishchit Dhanani i działało całkiem dobrze, co było: Wpisz tę linię do swojego Modelu
public $ primaryKey = '_id';
Gdzie _id jest ręcznym kluczem podstawowym

Dla mojej sprawy. Miałem tabelę użytkowników, a część moich użytkowników to uczniowie. Zatem klucz podstawowy w tabeli moich studentów to "user_id".
Dodanie tej linii do mojego modelu Studenta: public $ primaryKey = 'user_id';

Podczas aktualizacji mojego obiektu ucznia mogłem użyć metody save().

Nadzieja to pomaga

+1

Po prostu przegłosuj odpowiedzi, które uznasz za pomocne, zamiast pisać inne odpowiedzi, aby je powtórzyć. –

Powiązane problemy