20

Without using any gems how do I do this in rails?

Main Category
 Sub Category
 Sub Category
 Sub Category

Main Category
 Sub Category
 Sub Category
 Sub Category

Main Category
 Sub Category
 Sub Category
 Sub Category

I have a table that consists of | id | level1 | level2 |

Level 1 being the main category and Level 2 being the subcategory

I would like it displayed in the view like above.

After looking around on the internet everyone seems to recommend using acts-like-a-tree gem, but i want to avoid using them as I'm fairly new to rails and I would like to understand how to do things rather than turn to gems.

Your help is much apreciated

Model:

class Category < ActiveRecord::Base
belongs_to :catalogue
    has_many :subcategories, :class_name => "Category", :foreign_key => "parent_id", :dependent => :destroy
belongs_to :parent_category, :class_name => "Category"
end

Controller:

class CataloguesController < ApplicationController
  layout 'main'
  def index
   @cats = Catalogue.all
  end

  def categories
   @cat = Catalogue.find(params[:id])
  end

end

View:

<ul class="unstyled-list">

    <% @cat.categories.order([:level1]).each do |cat|%>
        <li><%=  cat.level1 %></li>
        <li><%= cat.level2 %></li>
    <% end %>
</ul>
4

2 回答 2

61

为子类别(或子子类别等)创建一个对其自身具有引用的模型:

class Category < ActiveRecord::Base
  has_many :subcategories, :class_name => "Category", :foreign_key => "parent_id", :dependent => :destroy
  belongs_to :parent_category, :class_name => "Category", :optional => true
end
  • has_many定义subcategories模型类型的关联Category。即它使用同一张表。
  • belongs_to定义了与父类别的关系,可通过以下方式访问@category.parent_category

有关模型关联的更多信息,has_many或者belongs_to,请阅读关联基础指南

要创建表,请使用此迁移:

class CreateCategories < ActiveRecord::Migration
  def self.up
    create_table :category do |t|
      t.string      :text
      # table name should be in plural 
      t.references  :parent_category, foreign_key: { to_table: :categories }
      t.timestamps
    end
  end
end

注意:此表格格式与您建议的(略有)不同,但我想这不是一个真正的问题。

迁移指南包含有关数据库迁移的更多信息。

在您的控制器中使用

def index
  @category = nil
  @categories = Category.find(:all, :conditions => {:parent_id => nil } )
end

查找没有父类的所有类别,即主要类别

要查找任何给定类别的所有子类别,请使用:

# Show subcategory
def show
  # Find the category belonging to the given id
  @category = Category.find(params[:id])
  # Grab all sub-categories
  @categories = @category.parent_category
  # We want to reuse the index renderer:
  render :action => :index
end

要添加新类别,请使用:

def new
  @category = Category.new
  @category.parent_category = Category.find(params[:id]) unless params[:id].nil?
end 

它创建一个新类别并设置父类别,如果提供的话(否则它成为主类别)

注意:我使用了旧的 rails 语法(由于懒惰),但对于现代版本的 Rails,原理是相同的。

在你的categories/index.html.erb你可以使用这样的东西:

<h1><%= @category.nil? ? 'Main categories' : category.text %></h1>
<table>
<% @categories.each do |category| %>
<tr>
  <td><%= link_to category.text, category_path(category) %></td>
  <td><%= link_to 'Edit', edit_category_path(category) unless category.parent.nil? %></td>
  <td><%= link_to 'Destroy', category_path(category), :confirm => 'Are you sure?', :method => :delete unless category.parent.nil? %></td>
</tr>
<% end %>
</table>
<p>
  <%= link_to 'Back', @category.parent_category.nil? ? categories_path : category_path(@category.parent_category) unless @category.nil? %>
  <%= link_to 'New (sub-category', new_category_path(@category) unless @category.nil? %>
</p>

它显示所选类别(或主类别)及其所有子类别的名称(在一个漂亮的表中)。它链接到所有子类别,显示类似的布局,但针对子类别。最后,它添加了一个“新子类别”链接和一个“返回”链接。

于 2013-01-07T14:36:45.500 回答
0
class CreateCategories < ActiveRecord::Migration
  def self.up
    create_table :category do |t|
      t.string      :text
      t.references  :parent
      t.timestamps
    end
  end
于 2019-11-17T05:35:15.010 回答