問題描述
我有 3 個表:posts
、tags
、post_tag
.
I have 3 tables: posts
, tags
, post_tag
.
每個Post
都有很多標簽,所以我對它們使用 hasMany
方法.但是,當我在下拉列表中選擇例如 3 個標簽時,我無法將它們添加到 post_tag
,因此我無法選擇和顯示每個帖子的標簽.
Each Post
has many tags so I use hasMany
method for them. But when I choose for example 3 tags in my dropdown list, I can't add them to post_tag
and as the result I can't select and show each post's tags.
我的發布
模型:
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
保存到 post_tag
表及其標簽 ID,但它不起作用.感謝您抽出寶貴時間.
I expect to save this post_id
save to post_tag
table with its tag ids,
but it doesn't work. Thanks for your time.
推薦答案
您的基本想法是正確的,但是您的代碼存在一些問題.有些正在阻止它工作,有些只是常規問題.
You have a basic idea right, but there are a few issues with your code. Some are stopping it from working and some are just conventional issues.
首先,這是一個 belongsTomany
關系(你有一個數據透視表)所以你必須將關系的兩邊定義為 belongsToMany
(即使 hasMany
是您考慮其中一側或兩側的方式).這是因為 Laravel 期望具有兩種不同關系類型的特定數據庫結構.
First off, this is a belongsTomany
relationship (you have a pivot table) so you must define both sides of the relationship as belongsToMany
(even if hasMany
is the way you think about one or both of the side of it). This is because Laravel expects a certain database structure with the two different relationship types.
另一個問題(您自己發現的)是您在實際保存帖子之前將標簽添加到關系中(通過 ->tag()->sync()
. 你必須先保存帖子(這樣 Laravel 才知道要為 post_id
添加到數據透視表中的 ID)然后添加關系.如果你擔心標簽部分失敗然后有不一致的數據庫你應該使用事務.
Another issue (that you found yourself) is that you are adding the tags to the relation (via ->tag()->sync()
before you've actually saved the post. You must first save the post (so that laravel knows what ID to add to the pivot table for post_id
) and then add the relations. If you are worried about the tags part failing and then having an inconsistent database you should use transactions.
最后,您遇到的約定"錯誤是多對多關系,根據定義,涉及結果集合.因此,tag
和 post
應該分別是 tags
和 posts
.
Finally, the 'convention' errors you have is that a belongs-to-many relationship, by definition, involves collections of results. As such, tag
and post
shoudl be tags
and posts
respectively.
這是我重寫的代碼版本:
So here's my rewritten version of your code:
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');
}
}
}
現在很多控制器代碼都以事務為中心——如果你不太關心它,那么你可以刪除它.此外,還有幾種方法可以完成這些事務——我采用了一種并不理想但用最少的代碼就可以說明問題的方法.
Now a lot of that controller code centres around the transaction stuff - if you don't care too much about that then you're all good to remove it. Also there are several ways to do that transaction stuff - I've gone with one that's not ideal but gets the point across in a minimal amount of code.
這篇關于將數據插入到 Laravel 中的數據透視表的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!