Категории и подкатегории модельные рельсы

Без использования каких-либо драгоценных камней, как это сделать в рельсах?

Основная категория
Подкатегория
Подкатегория
Подкатегория

Основная категория
Подкатегория
Подкатегория
Подкатегория

Основная категория
Подкатегория
Подкатегория
Подкатегория

У меня есть таблица, состоящая из | id | Уровень 1 | Уровень2 |

Уровень 1 является основной категорией, а уровень 2 - подкатегорией

Мне бы хотелось, чтобы он отображался в представлении, как показано выше.

Оглядываясь по Интернету, все, кажется, рекомендуют использовать драгоценный камень с эффектами, подобный дереву, но я хочу избежать использования их, поскольку я довольно новичок в рельсах, и я хотел бы понять, как делать вещи, а не превратитесь в драгоценные камни.

Ваша помощь сильно оценена

Модель:

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

Контроллер:

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

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

end

Вид:

<ul class="unstyled-list">

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

Ответы

Ответ 1

Создайте модель, которая ссылается на себя для подкатегории (или под-подкатегории и т.д.):

class Category < ActiveRecord::Base
  has_many :subcategories, :class_name => "Category", :foreign_key => "parent_id", :dependent => :destroy
  belongs_to :parent_category, :class_name => "Category"
end
  • has_many определяет ассоциацию subcategories типа модели Category. Т.е. он использует ту же таблицу.
  • belongs_to определяет отношение обратно к родительской категории (необязательно, не требуется)

Для получения дополнительной информации об ассоциациях моделей has_many или belongs_to прочитайте Руководство по основам ассоциаций.

Чтобы создать таблицу, используйте эту миграцию:

class CreateCategories < ActiveRecord::Migration
  def self.up
    create_table :category do |t|
      t.string      :text
      t.references  :parent
      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.subcategories
  # We want to reuse the index renderer:
  render :action => :index
end

Чтобы добавить использование новой категории:

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

Создает новую категорию и устанавливает родительский элемент, если он предоставлен (в противном случае он становится главной категорией)

Примечание. Я использовал старый синтаксис рельсов (из-за лени), но для 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>

Здесь отображается название выбранной категории (или Основной категории) и всех ее подкатегорий (в таблице с хорошей таблицей). Он ссылается на все подкатегории, демонстрируя аналогичный макет, но для подкатегории. В конце он добавляет ссылку "новая подкатегория" и "обратная связь".

Примечание. Мой ответ немного расширился... Я скопировал и модифицировал его из одного из моих проектов, который использует аналогичную конструкцию (для (под) меню). Поэтому, надеюсь, я ничего не сломал во время модификаций...:)