Skip to content

Instantly share code, notes, and snippets.

@ruevaughn
Created April 21, 2012 21:16
Show Gist options
  • Save ruevaughn/2439635 to your computer and use it in GitHub Desktop.
Save ruevaughn/2439635 to your computer and use it in GitHub Desktop.
Implementing the SQL structured Nested Set gem, allowing for infinite nesting. This allows for drag and dropable lists.
class CategoriesController < ApplicationController
before_filter :add_breadcrumbs
before_filter :authorize, only: [:new, :create, :new_subcategory, :update, :edit]
def new
add_breadcrumb "New Category", new_category_path
@category = params[:id] ? Category.find(params[:id]).children.new : Category.new
@count = Category.count
end
def new_subcategory
add_breadcrumb "New Subcategory", new_subcategory_categories_path
@category = params[:id] ? Category.find(params[:id]).children.new : Category.new
end
def create
@category = params[:id] ? Category.find(params[:id]).children.new(params[:category]) : Category.new(params[:category])
if @category.save
redirect_to products_path, :notice => "Category created! Woo Hoo!"
else
render "new"
end
end
def edit
@category = Category.find(params[:id])
end
def edit_subcategory
@category = Category.find(params[:id])
end
def destroy
@category = Category.find(params[:id])
@category.destroy
flash[:notice] = "Category has been obliterated!"
redirect_to products_path
end
def update
@category = Category.find(params[:id])
if @category.update_attributes(params[:category])
flash[:notice] = "Changed it for ya!"
redirect_to products_path
else
flash[:alert] = "Category has not been updated."
render :action => "edit"
end
end
def sort
params[:category].each_with_index do |id, index|
Category.update_all({position: index+1}, {id: id})
end
end
def add_breadcrumbs
add_breadcrumb "Admin", admin_sites_path
add_breadcrumb "Manage Products", products_path
end
end
class Category < ActiveRecord::Base
acts_as_nested_set
acts_as_list :scope => :parent_id
attr_accessible :name, :parent_id, :position, :image
has_many :products
mount_uploader :image, CategoryUploader
scope :position, order("position asc")
scope :categories, where("depth IS NULL")
scope :subcategories, where("parent_id IS NOT NULL")
scope :with_depth_below, lambda { |level|
where(self.arel_table[:depth].lt(level))
}
end
<nav id="admin">
<ul>
<li><%= link_to "New Category", new_category_path %></li>
<li><%= link_to "New Subcategory", new_subcategory_categories_path %></li>
<li><%= link_to "New product", new_product_path %></li>
</ul>
</nav>
<h3>Categories</h3>
<div id="category">
<ul id="sortable">
<% for cat in Category.roots %>
<li id='category_<%= cat.id %>'>
<span><%= cat.name %></span>
<span>Depth: <%= cat.depth %>
<%= link_to raw('<span class="button-edit">Edit</span>'), edit_category_path(cat) %>
<%= link_to raw('<span class="button-delete">Delete</span>'), cat, :method => :delete, :confirm => "Are you sure you want to delete this category?" %><br /> <br />
<%= render 'shared/children', :item => cat unless cat.leaf? %>
</li>
<hr>
<% end %>
<!-- end category -->
<h3><a href='#' id='serialize'>Save Order</a> | <a href="javascript:location.reload(true)">Reset</a></h3>
</ul>
</div>
Jensenlocksmithing::Application.routes.draw do
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
get "log_out" => "sessions#destroy", as: "log_out"
get "log_in" => "sessions#new", as: "log_in"
resources :sites, except: [:new, :show, :destroy, :create] do
collection do
get :home
get :about_us
get :faq
get :discounts
get :services
get :contact_us
get :admin
get :posts
end
end
resources :logos
resources :users
resources :abouts
resources :sessions
resources :coupons
resources :monthly_posts
resources :reviews, except: [:new, :show, :destroy, :create]
resources :contacts, except: [:new, :show, :destroy, :create, :index]
resources :categories, except: [:index, :show] do
collection do
post :sort
get :new_subcategory
get :edit_subcategory
end
resources :children, :controller => :categories, :only => [:index, :new, :create, :new_subcategory]
end
resources :products do
member do
put :move_up
put :move_down
end
end
resources :faqs do
collection { post :sort }
end
root :to => 'sites#home' # handles /en/
match "/savesort" => 'sites#savesort'
match "*path", to: "sites#not_found" # handles /en/fake/path/whatever
end
root to: redirect("/#{I18n.default_locale}") # handles /
match 'request_bid' => 'request_bid#new', :as => 'request_bid', :via => :get
match 'request_bid' => 'request_bid#create', :as => 'request_bid', :via => :post
match '*path', to: redirect("/#{I18n.default_locale}/%{path}")
end
<ul>
<% item.children.each do |child| %>
<li id='category_<%=child.id %>'>
<span><%= child.name %> Depth: <%= child.depth %><%= link_to 'Edit', edit_category_path(child) %>
<%= link_to 'Delete', child, :method => :delete, :confirm => "Are you sure you want to delete this Subcategory?" %> </span>
<% child.products.position.each do |product| %>
<br /><%= link_to "UP", move_up_product_path(product.id), method: :put %> |
<%= link_to "Down", move_down_product_path(product), method: :put %> ----------<%= product.position %>
<%= product.name %>
<%= image_tag product.image_url if product.image? %>
<%= link_to 'Edit', edit_product_path(product) %>
<%= link_to 'Delete', product, :method => :delete, :confirm => "Are you sure you want to delete this product?" %> <br />
<% end %>
<%= render 'shared/children', :item => child unless child.leaf? %>
</li>
<% end %> <br />
</ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment