【发布时间】:2014-09-19 01:42:52
【问题描述】:
我正在通过 Rails 创建博客。我通过多对多关系关联帖子和类别模型。如何在此模型中合并子类别?
【问题讨论】:
标签: ruby-on-rails many-to-many blogs categories
我正在通过 Rails 创建博客。我通过多对多关系关联帖子和类别模型。如何在此模型中合并子类别?
【问题讨论】:
标签: ruby-on-rails many-to-many blogs categories
最好的方法是使用一个层次结构 gems,通常是Ancestry 或Closure_Tree 来为你的categories 创建一个“树”类型的结构。然后,您就可以将blogs 与每个类别相关联,从而创建您需要的层次结构功能。
我们之前已经实现了这一点 - 使用 Ancestry gem:
类别
从上图中可以看出,您缺少的“秘诀”是您的类别不是基于层次结构的结构。
这很重要的原因是,如果您将博客文章与特定的categories 相关联,为了使这些类别实现您想要的“子类别”结构,您需要能够创建一个支持它的系统,因此是 hierarchy 宝石。
具体来说,您目前正在创建一个单独的sub_category.rb 模型。正确的做法是使用 one 模型 - Category - 并使用层次结构宝石为您提供树结构。
我们是这样做的:
#app/models/category.rb
class Category < ActiveRecord::Base
has_ancestry #-> enables the "ancestry" gem
has_and_belongs_to_many :posts
end
#app/models/post.rb
class Post < ActiveRecord::Base
has_and_belongs_to_many :categories #-> you'll need a blogs_categories table with blog_id | category_id
end
控制器
从您的角度来看,需要注意的重要一点是,您需要确保您有正确的“控制器操作”,以便为您的博客分配正确的类别:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
@post = Post.new
end
def create
@post = Post.new post_params
@post.save
end
private
def post_params
params.require(:post).permit(:title, :body, :category_ids)
end
end
查看
最后,此设置的真正魔力在于,如果您想以层次/树格式显示您的项目,您将能够使用 Ancestry 关联方法让您能够创建“嵌套”列表:
为此,您只需要使用一个partial,它将call the children of the parent objects,允许您显示“树”类型层次结构(以及创建子类别):
#app/views/categories/_category.html.erb
<ol class="categories">
<% collection.arrange.each do |category, sub_item| %>
<li>
<!-- Category -->
<%= link_to category.title, edit_admin_category_path(category) %>
<!-- Children -->
<% if category.has_children? %>
<%= render partial: "category", locals: { collection: category.children } %>
<% end %>
</li>
<% end %>
</ol>
这将允许您调用以下内容:
#app/views/categories/index.html.erb
<%= render partial: "category", locals: { collection: @categories } %>
【讨论】:
创建一个 sub_categories 模型,如下所示:
# post.rb
has_and_belongs_to_many :categories
has_many :sub_categories
# category.rb
has_and_belongs_to_many :posts
has_many :sub_categories
# sub_category.rb
belongs_to :category
belongs_to :post
# delegate attributes like so
delegate: :title, to: :category
在rails guide了解更多关于它们的信息
【讨论】: