2014-07-03 4 views
4

привет У меня есть 3 таблицы => сообщения, теги, post_tagвставки данных в сводной таблице в Laravel

каждый пост имеет много тегов, поэтому я использую hasMany метод для них. но когда я выбираю для примера 3 тега в моем выпадающем списке, я не могу добавить их в post_tag, и в результате я не могу выбрать и показать теги каждого сообщения.

это мой пост модель:

class Post extends Eloquent{ 
public function tag() 
     { 
      return $this->hasMany('Tag'); 
     } 
    } 

это мой тег модель:

class Tag extends Eloquent{ 
public function post() 
     { 
      return $this->belongsToMany('Post'); 
     } 

}

и это мой PostController:

class postController extends BaseController{ 

public function addPost(){ 

    $post=new Post; 

    $post_title=Input::get('post_title'); 
    $post_content=Input::get('post_content'); 
    $tag_id=Input::get('tag'); 

    $post->tag()->sync($tag_id); 
    $post->save(); 

Я ожидаю, чтобы сохранить это post_id сохранить в pos таблица t_tag с идентификаторами тегов; но он не работает. спасибо за ваше время.

+1

Если отношение имеет сводную таблицу, то обе стороны должны быть «принадлежать многим». Также вы действительно должны называть метод 'tags' не' tag', поскольку это * Многие отношения. – alexrussell

+0

@alexrussell да, ты прав :). и другая проблема была '$ post-> tag() -> sync ($ tag_id); $ post-> save(); 'эти места для заметок должны быть заменены. спасибо – saha

+0

Я добавил ответ, который объясняет мой комментарий немного больше и включает в себя вашу собственную коррекцию. – alexrussell

ответ

2

У вас есть основная идея права, но есть несколько проблем с вашим кодом. Некоторые останавливают его от работы, а некоторые - обычные проблемы.

Во-первых, это belongsTomany отношения (у вас есть сводную таблицу), так что вы должны определить, обе стороны отношений, как belongsToMany (даже если hasMany путь вы думаете об один или оба его стороны). Это связано с тем, что Laravel ожидает определенную структуру базы данных с двумя разными типами отношений.

Еще одна проблема (что вы обнаружили) заключается в том, что вы добавляете теги в отношение (через ->tag()->sync(), прежде чем вы действительно сохранили сообщение. Сначала вы должны сохранить сообщение (так что laravel знает, какой идентификатор добавить сводная таблица для post_id), а затем добавьте отношения.Если вы беспокоитесь о сбое в работе с тегами и затем используете несогласованную базу данных, вы должны использовать транзакции.

Наконец, для многих, по определению, включает в себя сбор результатов. Таким образом, tag и post shoudl будут tags и posts соответственно.

Так вот моя переписана версия коды:

class Post extends Eloquent 
{ 
    public function tags() 
    { 
     return $this->belongsToMany('Tag'); 
    } 
} 

class Tag extends Eloquent 
{ 
    public function posts() 
    { 
     return $this->belongsToMany('Post'); 
    } 
} 

class PostController extends BaseController 
{ 
    public function addPost() 
    { 
     // assume it won't work 
     $success = false; 

     DB::beginTransaction(); 

     try { 
      $post = new Post; 

      // maybe some validation here... 

      $post->title = Input::get('post_title'); 
      $post->content = Input::get('post_content'); 

      if ($post->save()) { 
       $tag_ids = Input::get('tags'); 
       $post->tags()->sync($tag_ids); 
       $success = true; 
      } 
     } catch (\Exception $e) { 
      // maybe log this exception, but basically it's just here so we can rollback if we get a surprise 
     } 

     if ($success) { 
      DB::commit(); 
      return Redirect::back()->withSuccessMessage('Post saved'); 
     } else { 
      DB::rollback(); 
      return Redirect::back()->withErrorMessage('Something went wrong'); 
     } 
    } 
} 

Сейчас много этого код контроллера центров вокруг вещи сделки - если вы не заботитесь слишком много о том, что тогда вы все хорошо, чтобы удалить Это. Также есть несколько способов сделать этот материал транзакций - я пошел с тем, который не идеален, но имеет смысл в минимальном количестве кода.

3

Метод sync() хочет получить массив. Он должен работать, если вы просто поставить тег идентификатор в пределах одного, например, так:

$post->tag()->sync([$tag_id]); 
+0

'Вызов неопределенного метода Illuminate \ Database \ Query \ Builder :: sync()'. он всегда появляется :( – saha

+0

@joelhinz, насколько я могу различить вышеприведенный код, действительно отправлял бы массив - '$ tag_id' появляется в форме' Input :: get ('tag') ', которая во вступительном порядке говорит OP: когда я выбираю, например, теги 3 в раскрывающемся списке, «который предполагает, что это массивный вход. Это говорит о том, что мы не должны предполагать. – alexrussell

+0

@alexrussell Очень хороший момент, спасибо. –

1

Чтобы вставить вам данные в сводную таблице имя diplome_user, просто следовать моему примеру: моя сводная таблица выглядит как:

enter image description here

//this is Diplome Model 

    class Diplome extends Model 
    { 
    public function users() 
     { 
      return $this->belongsToMany('App\User','diplome_user')->withPivot('etablissement', 'annee', 'mention');; 
     } 
    } 

Теперь внутри тебя мой DiplomeController, я могу сделайте этот запрос:

$user = Auth::user(); 

потому что мне нужен пользователь, я просто беру подключенный, после него, Я создаю один экземпляр Diplome как:

$diplome = new Diplome(); 
$diplome->libelle = "the name"; 
$diplome->decription= "description of the ..."; 
$diplome->save(); 

теперь самый важный шаг:

$diplome->users()->attach($user, ['etablissement'=> 'bib', 
              'annee'=>'2015', 
              'mention'=>'AB', 
              ]); 

Вот результат:

enter image description here

+0

спасибо #halfer !!!! –

Смежные вопросы