类别和子类别模型轨道

Oll*_*619 18 model ruby-on-rails categories ruby-on-rails-3.2

如果不使用任何宝石,我如何在rails中执行此操作?

主要类别
 子类别
 子类别
 子类别

主要类别
 子类别
 子类别
 子类别

主要类别
 子类别
 子类别
 子类别

我有一个由|组成的表 id | level1 | level2 |

1级是主要类别,2级是子类别

我想在上面的视图中显示它.

在互联网上四处看看之后,每个人似乎都建议使用类似行为的宝石,但我想避免使用它们,因为我对rails很新,我想了解如何做事而不是转向宝石.

你的帮助很大

模型:

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
Run Code Online (Sandbox Code Playgroud)

控制器:

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

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

end
Run Code Online (Sandbox Code Playgroud)

视图:

<ul class="unstyled-list">

    <% @cat.categories.order([:level1]).each do |cat|%>
        <li><%=  cat.level1 %></li>
        <li><%= cat.level2 %></li>
    <% end %>
</ul>
Run Code Online (Sandbox Code Playgroud)

Veg*_*ger 52

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

class Category < ActiveRecord::Base
  has_many :subcategories, :class_name => "Category", :foreign_key => "parent_id", :dependent => :destroy
  belongs_to :parent_category, :class_name => "Category"
end
Run Code Online (Sandbox Code Playgroud)
  • has_many定义了一个subcategories模型类型的关联Category.即它使用相同的表.
  • belongs_to限定回父类别的关系(可选,不是必需的)

有关模型关联的更多信息,has_manybelongs_to,阅读协会基础知识手册.

要创建表,请使用以下迁移:

class CreateCategories < ActiveRecord::Migration
  def self.up
    create_table :category do |t|
      t.string      :text
      t.references  :parent
      t.timestamps
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

注意:此表格格式(稍微)与您提议的不同,但我认为这不是一个真正的问题.

" 迁移指南"包含有关数据库迁移的详细信息.

在您的控制器中使用

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

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

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

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

要添加新类别,请使用:

def new
  @category = Category.new
  @category.parent = Category.find(params[:id]) unless params[:id].nil?
end 
Run Code Online (Sandbox Code Playgroud)

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

注意:我使用旧的rails语法(由于懒惰),但对于Rails 3.2,原理是相同的.

在你的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.nil? ? categories_path : category_path(@category.parent) unless @category.nil? %>
  <%= link_to 'New (sub-category', new_category_path(@category) unless @category.nil? %>
</p>
Run Code Online (Sandbox Code Playgroud)

它显示所选类别(或主类别)的名称及其所有子类别(在一个漂亮的表中).它链接到所有子类别,显示类似的布局,但是对于子类别.最后,它添加了一个"新的子类别"链接和一个"后退"链接.

注意:我的答案变得有点广泛......我从我的一个使用类似结构的项目(用于(子)菜单)复制和修改它.所以希望我在修改过程中没有破坏任何东西...... :)

  • 在Rails 5中,您需要将`optional:true`添加到`belongs_to`关系中.`belongs_to:parent_category,class_name:"Category",可选:true`,因为每当我们定义`belongs_to`关联时,都需要有相关的记录. (3认同)
  • 为了使`:parent_category`工作,我需要添加`:foreign_key =>"parent_id"`.否则,它返回零. (2认同)
  • 在Rails 5中,如果要创建迁移以添加到名为`categories`的现有表,则可以使用:`add_reference:categories,:parent,foreign_key:{to_table :: categories}` (2认同)