| 1 |
module SymetrieCom |
|---|
| 2 |
module Acts #:nodoc: |
|---|
| 3 |
|
|---|
| 4 |
# This module provides some helpers for the model classes using acts_as_nested_set. |
|---|
| 5 |
# It is included by default in all views. If you need to remove it, edit the last line |
|---|
| 6 |
# of init.rb. |
|---|
| 7 |
# |
|---|
| 8 |
module BetterNestedSetHelper |
|---|
| 9 |
|
|---|
| 10 |
# Prints a line of ancestors with links, on the form |
|---|
| 11 |
# root > parent > item |
|---|
| 12 |
# |
|---|
| 13 |
# == Usage |
|---|
| 14 |
# Default is to use links to {your_cotroller}/show with the first string column of your model. |
|---|
| 15 |
# You can tweak this by passing your parameters, or better, pass a block that will receive |
|---|
| 16 |
# an item from your nested set tree and a boolean flag (true for current item) and that |
|---|
| 17 |
# should return the line with the link. |
|---|
| 18 |
# |
|---|
| 19 |
# == Examples |
|---|
| 20 |
# |
|---|
| 21 |
# nested_set_full_outline(category) |
|---|
| 22 |
# |
|---|
| 23 |
# # non standard actions and separators |
|---|
| 24 |
# nested_set_full_outline(category, :action => :search, :separator => ' | ') |
|---|
| 25 |
# |
|---|
| 26 |
# # with a block that will return the link to the item |
|---|
| 27 |
# # note that the current item will lead to another action |
|---|
| 28 |
# nested_set_full_outline(category) { |item, current?| |
|---|
| 29 |
# if current? |
|---|
| 30 |
# link_to "#{item.name} (#{item.})", product_url(:action => :show_category, :category => item.whole_url) |
|---|
| 31 |
# else |
|---|
| 32 |
# link_to "#{item.name} (#{item.})", category_url(:action => :browse, :criteria => item.whole_url) |
|---|
| 33 |
# end |
|---|
| 34 |
# } |
|---|
| 35 |
# |
|---|
| 36 |
# == Params are: |
|---|
| 37 |
# +item+ - the object to display |
|---|
| 38 |
# +hash+ - containing : |
|---|
| 39 |
# * +text_column+ - the title column, defaults to the first string column of the model |
|---|
| 40 |
# * +:action+ - the action to be called (defaults to :show) |
|---|
| 41 |
# * +:controller+ - the controller name (defaults to the model name) |
|---|
| 42 |
# * +:separator+ - the separator (defaults to >) |
|---|
| 43 |
# * +&block+ - a block {Â |item, current?| ... item.name } |
|---|
| 44 |
# |
|---|
| 45 |
def nested_set_full_outline(item, options={}) |
|---|
| 46 |
return if item.nil? |
|---|
| 47 |
raise 'Not a nested set model !' if !item.respond_to? :acts_as_nested_set_options |
|---|
| 48 |
|
|---|
| 49 |
options = { |
|---|
| 50 |
:text_column => options[:text_column] || item.acts_as_nested_set_options[:text_column], |
|---|
| 51 |
:action => options[:action] || :show, |
|---|
| 52 |
:controller => options[:controller] || item.class.to_s.underscore, |
|---|
| 53 |
:separator => options[:separator] || ' > ' } |
|---|
| 54 |
|
|---|
| 55 |
s = '' |
|---|
| 56 |
for it in item.ancestors |
|---|
| 57 |
if block_given? |
|---|
| 58 |
s += yield(it) + options[:separator] |
|---|
| 59 |
else |
|---|
| 60 |
s += link_to( it[options[:text_column]], { :controller => options[:controller], :action => options[:action], :id => it }) + options[:separator] |
|---|
| 61 |
end |
|---|
| 62 |
end |
|---|
| 63 |
if block_given? |
|---|
| 64 |
s + yield(item) |
|---|
| 65 |
else |
|---|
| 66 |
s + h(item[options[:text_column]]) |
|---|
| 67 |
end |
|---|
| 68 |
end |
|---|
| 69 |
|
|---|
| 70 |
# Returns options for select. |
|---|
| 71 |
# You can exclude some items from the tree. |
|---|
| 72 |
# You can pass a block receiving an item and returning the string displayed in the select. |
|---|
| 73 |
# |
|---|
| 74 |
# == Usage |
|---|
| 75 |
# Default is to use the whole tree and to print the first string column of your model. |
|---|
| 76 |
# You can tweak this by passing your parameters, or better, pass a block that will receive |
|---|
| 77 |
# an item from your nested set tree and that should return the line with the link. |
|---|
| 78 |
# |
|---|
| 79 |
# == Examples |
|---|
| 80 |
# |
|---|
| 81 |
# nested_set_options_for_select(Category) |
|---|
| 82 |
# |
|---|
| 83 |
# # show only a part of the tree, and exclude a category and its subtree |
|---|
| 84 |
# nested_set_options_for_select(selected_category, :exclude => category) |
|---|
| 85 |
# |
|---|
| 86 |
# # add a custom string |
|---|
| 87 |
# nested_set_options_for_select(Category, :exclude => category) { |item| "#{' ' * item.level}#{item.name} (#{item.url})" } |
|---|
| 88 |
# |
|---|
| 89 |
# == Params |
|---|
| 90 |
# * +class_or_item+ - Class name or item to start the display with |
|---|
| 91 |
# * +text_column+ - the title column, defaults to the first string column of the model |
|---|
| 92 |
# * +&block+ - a block {Â |item| ... item.name } |
|---|
| 93 |
# If no block passed, uses {|item| "#{'··' * item.level}#{item[text_column]}"} |
|---|
| 94 |
def nested_set_options_for_select(class_or_item, options=nil) |
|---|
| 95 |
# find class |
|---|
| 96 |
if class_or_item.is_a? Class |
|---|
| 97 |
first_item = class_or_item.root |
|---|
| 98 |
else |
|---|
| 99 |
first_item = class_or_item |
|---|
| 100 |
end |
|---|
| 101 |
raise 'Not a nested set model !' if !first_item.respond_to? :acts_as_nested_set_options |
|---|
| 102 |
|
|---|
| 103 |
# exclude some items and all their children |
|---|
| 104 |
if options.is_a? Hash |
|---|
| 105 |
text_column = options[:text_column] |
|---|
| 106 |
options.delete_if { |key, value| key != :exclude } |
|---|
| 107 |
else |
|---|
| 108 |
options = nil |
|---|
| 109 |
end |
|---|
| 110 |
text_column ||= first_item.acts_as_nested_set_options[:text_column] |
|---|
| 111 |
|
|---|
| 112 |
tree = first_item.full_set(options) |
|---|
| 113 |
if block_given? |
|---|
| 114 |
tree.map{|item| [yield(item), item.id] } |
|---|
| 115 |
else |
|---|
| 116 |
tree.map{|item| [ "#{'··' * item.level}#{item[text_column]}", item.id]} |
|---|
| 117 |
end |
|---|
| 118 |
end |
|---|
| 119 |
end |
|---|
| 120 |
end |
|---|
| 121 |
end |
|---|
| 122 |
|
|---|