Ответ 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>
Здесь отображается название выбранной категории (или Основной категории) и всех ее подкатегорий (в таблице с хорошей таблицей). Он ссылается на все подкатегории, демонстрируя аналогичный макет, но для подкатегории. В конце он добавляет ссылку "новая подкатегория" и "обратная связь".
Примечание. Мой ответ немного расширился... Я скопировал и модифицировал его из одного из моих проектов, который использует аналогичную конструкцию (для (под) меню). Поэтому, надеюсь, я ничего не сломал во время модификаций...:)