How do you create a model with categories that has subcategories (using Rails)?

老子叫甜甜 提交于 2020-01-01 19:14:32

问题


I am creating a blog through Rails. I am relating the posts and categories models through a many-to-many relationship. How do I incorporate subcategories in this model?


回答1:


Hierarchy

The best way is to use one of the hierarchy gems, typically Ancestry or Closure_Tree to create a "tree" type structure for your categories. You'll then be able to associate blogs with each category, creating the hierarchy functionality you need.

We've achieved this before - using the Ancestry gem:


Categories

As you can see from the above image, the "secret sauce" you're missing is that your categories are not in a hierarchy-based structure.

The reason this is important is because if you associate your blog posts with specific categories, in order for those categories to achieve the "sub category" structure you desire, you need to be able to create a system which supports it, hence the hierarchy gems.

Specifically, you're currently working on creating a separate sub_category.rb model. The right way to do it is to keep it with one model - Category - and use the hierarchy gems to provide you with the tree infrastructure.

Here's how we do it:

#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

Controller

The important thing to note from your perspective is that you will need to ensure you have the right "controller actions" in place, to assign the correct category to your blog:

#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

View

Finally, the real magic of this setup is that if you want to display your items in a hierachy / tree format, you'll be able to use the Ancestry association methods to give you the ability to create "nested" lists:

To do this, you'll just need to use a partial, which will call the children of the parent objects, allowing you to show a "tree" type hierarchy (as well as creating subcategories):

#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>

This will allow you to call the following:

#app/views/categories/index.html.erb
<%= render partial: "category", locals: { collection: @categories } %>



回答2:


Create a sub_categories model, like so:

# 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

Read more about them in the rails guide



来源:https://stackoverflow.com/questions/25925068/how-do-you-create-a-model-with-categories-that-has-subcategories-using-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!