【问题标题】:How do you create a model with categories that has subcategories (using Rails)?如何创建具有子类别的模型(使用 Rails)?
【发布时间】:2014-09-19 01:42:52
【问题描述】:

我正在通过 Rails 创建博客。我通过多对多关系关联帖子和类别模型。如何在此模型中合并子类别?

【问题讨论】:

    标签: ruby-on-rails many-to-many blogs categories


    【解决方案1】:

    Hierarchy

    最好的方法是使用一个层次结构 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 } %>
    

    【讨论】:

      【解决方案2】:

      创建一个 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了解更多关于它们的信息

      【讨论】:

        猜你喜欢
        • 2015-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 2016-04-24
        • 2017-04-08
        • 1970-01-01
        相关资源
        最近更新 更多