posts
、tags
、post_tag
の3つのテーブルがあります。
各Post
には多くのタグがあるので、それらにはhasMany
メソッドを使用します。しかし、ドロップダウンリストでたとえば3つのタグを選択すると、それらをpost_tag
に追加できず、その結果、各投稿のタグを選択して表示することができません。
私のPost
モデル:
class Post extends Eloquent{
public function tag()
{
return $this->hasMany('Tag');
}
}
私の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
をタグIDとともにpost_tag
テーブルに保存する予定ですが、機能しません。御時間ありがとうございます。
基本的な考え方は正しいですが、コードにはいくつかの問題があります。動作を停止しているものもあれば、従来の問題であるものもあります。
まず、これはbelongsTomany
関係(ピボットテーブルがあります)であるため、関係の両側をbelongsToMany
として定義する必要があります(hasMany
があなたの考え方であっても)その側面の約片方または両方)。これは、Laravelは、2つの異なる関係タイプを持つ特定のデータベース構造を想定しているためです。
もう1つの問題(自分で見つけた)は、実際に投稿を保存する前に(->tag()->sync()
を介して)リレーションにタグを追加していることです。最初に投稿を保存する必要があります(laravelは、post_id
)のピボットテーブルに追加するIDを認識してから、リレーションを追加します。タグ部分が失敗し、データベースに一貫性がないことが心配な場合は、トランザクションを使用する必要があります。
最後に、あなたが持っている「従来の」エラーは、定義上、多くに属する関係には結果の収集が含まれるということです。そのため、tag
とpost
はそれぞれ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');
}
}
}
現在、そのコントローラーコードの多くはトランザクション関連のものを中心にしています。それについてあまり気にしないのであれば、それを削除しても問題ありません。また、そのトランザクションを実行する方法はいくつかあります。理想的ではないものの、最小限のコードで要点を理解できる方法を採用しました。
ピボットテーブル名diplome_userにデータを挿入するには、次の例に従ってください。ピボットテーブルは次のようになります。
//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のインスタンスを1つ作成します。
$diplome = new Diplome();
$diplome->libelle = "the name";
$diplome->decription= "description of the ...";
$diplome->save();
今最も重要なステップは次のとおりです。
$diplome->users()->attach($user, ['etablissement'=> 'bib',
'annee'=>'2015',
'mention'=>'AB',
]);
結果は次のとおりです。
sync()
メソッドは配列を必要としています。次のように、タグIDを1つに入れるだけで機能するはずです。
$post->tag()->sync([$tag_id]);