问题
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