Laravel访问器,将类别id转换为类别标题


Laravel accessor to convert category ids to category titles

感谢您花时间帮助我。

我正在建立一个可以关联类别的博客。我将相关的猫按id保存在blog表中。

例如:category_blog_id = 1,3,9

我想通过标题检索类别,所以我认为最好的方法是在blog模型上编写一个访问器。

谁能给我指一下正确的方向吗?

我应该添加使用CategoryBlog模型,然后爆炸category_blog_id和运行foreach吗?

这就是我一直在尝试的,但它还没有完全正常工作,我想知道是否有一个更好的,更拉拉维尔的方式来做到这一点?

许多谢谢。

实际上,PostCategory之间的关系可能是many-to-many,因为Category可以有多个帖子,Post也可以在多个Category中。因此,如果是这种情况,那么您应该创建三个表,如:

Table - posts:

id  | post_title  | post_slug  | post_content | Others...

Table - categories:

id  | category_title  | category_slug  | Others...

Table - category_post(数据透视表/维护职位和类别之间的关系):

id  | category_id  | post_id

那么你需要two模型作为PostCategory:

// Post model
class Post extends Eloquent {
    public function categories() {
        return $this->belongsToMany('Category');
    }
}
// Category model
class Category extends Eloquent {
    public function posts() {
        return $this->belongsToMany('Post');
    }
}

使用如下命令创建分类:

category::create(array(...)); // Input::all() (Mass Assignment)

你也可以创建一个Category:

$category = new category;
$category->category_title = Input::get('category_title');
$category->category_slug = Input::get('category_slug');
// other fields (if have any)
$category->save();

现在创建Post并附加类别:

$post =  new Post; // Assume that, this is the first post so id would be 1
$post->title = 'My Post'; // Input::get('post_title');
$post->slug = 'mypost';   // Input::get('post_slug');
// Assign other values like post_content etc then
$post->save();

一旦Post被保存,那么:

// Attach two categories with this post using category id
$post->categories()->sync(array(1, 2)); // These (1, 2) are category ids

现在你有了一个Post这个Post属于类别,换句话说,这篇文章是在两个类别下创建的通过同步文章和类别,你实际上是在文章和两个类别之间建立了一个关系这些关系数据将保存在category_post表中根据这个例子,category_post表将包含如下内容:

id  | category_id  | post_id
----------------------------
1   |      1       |   1
2   |      2       |   1

现在您可以使用Post模型query来获取所有具有以下类别的帖子:

$posts = Post::with('categories')->get();

也可以通过id找到与之相关的类别,使用如下命令:

$post = Post::with('categories')->find(1);

您可以使用以下命令访问相关类别:

$post->categories->get(0); // first category from the collection
$post->categories->get(1); // second category from the collection

如果您像这样将Post模型集合传递给视图;

$posts = Post::with('categories')->get();
return View::make('post.index')->with('posts', $posts);

然后在视图中,你可以像这样循环所有的帖子和类别:

@foreach($posts as $post)
    {{ $post->post_title }}
    {{ $post->post_content }}
    @foreach($post->categories as $category)
        {{ $category->title }}
    @endforeach
@endforeach

您也可以使用Category模型,如:

// Get all categories with related posts
$categories = Category::with('posts')->get();
// Get a category using it's id with related posts
$category = Category::with('posts')->find(2); // Category id 2

这是基本思想,更多内容请阅读手册(Eloquent ORM)

不要在数据库中存储分隔的值!相反,除了blogscategories表之外,还引入了一个多对多(透视)表blog_category。它将允许您使用关系数据库提供的方法(例如join)正常地维护和查询数据。

这个表的模式可能是这样的:

CREATE TABLE blog_category
(
  blog_id INT UNSIGNED NOT NULL,
  category_id INT UNSIGNED NOT NULL,
  PRIMARY KEY (blog_id, category_id),
  FOREIGN KEY (blog_id) REFERENCES blogs (id),
  FOREIGN KEY (category_id) REFERENCES categories (id)
);

这样的表的Laravel迁移可能看起来像

class CreateBlogCategoryTable extends Migration {
    public function up() {
        Schema::create('blog_category', function(Blueprint $table)
        {
            $table->integer('blog_id')->unsigned();
            $table->integer('category_id')->unsigned();
            $table->foreign('blog_id')->references('id')->on('blogs');
            $table->foreign('category_id')->references('id')->on('categories');
            $table->primary(['blog_id', 'category_id']);
        });
    }
    public function down() {
        Schema::drop('blog_category');
    }
}

Laravel Eloquent开箱即用支持多对多关系:

Blog模型

class Blog extends Eloquent {
    public function categories() {
        return $this->belongsToMany('Category');
    }
}

Category模型

class Category extends Eloquent {
    public function blogs() {
        return $this->belongsToMany('Blog');
    }    
}

现在您可以通过分类访问博客

$blogs = Category::find(1)->blogs();

或特定博客所属的类别

$categories = Blog::find(1)->categories();