Nested Set Error未定义方法`self_and_descendants'for#< ActiveRecord :: Relation:0x52c4a30> [英] Nested Set Error undefined method `self_and_descendants' for #<ActiveRecord::Relation:0x52c4a30>
问题描述
我在我的代码中使用了Nested_Set gem来排序类别,子类别和产品。我试图限制我的嵌套集的深度/级别不会更深,然后2.目前我得到错误
嵌套设置错误未定义的方法`self_and_descendants'为#< ActiveRecord :: Relation:0x52c4a30>
我正在尝试创建一个克制菜单式样式,并试图使其拖动
这是我的代码:
有人可以浏览它并帮助我理解这个错误吗?感谢
Category.rb
class Category< ActiveRecord :: Base
acts_as_nested_set
acts_as_list:scope => :parent_id
has_many:products
scope:category,其中(parent_id IS NULL)
scope:子类别,其中(parent_id IS NOT NULL)
scope:with_depth_below, lambda {| level | (self.arel_table [:depth] .lt(level))}
end
categories_controller
class CategoriesController< ApplicationController
def new
@category = params [:id]? Category.find(params [:id])。children.new:Category.new
@count = Category.count
end
$ b $ def new_subcategory
@category = params [:id]? Category.find(params [:id])。children.new:Category.new
@ category_2_deep = Category.with_depth_below(2)
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 => 创建的类别!Woo Hoo!
else
渲染新
结束
结束
def编辑
@category = Category.find(params [:id])
end
$ b def edit_subcategory
@category = Category.find(params [:id])
@ category_2deep = Category.with_depth_below(2).arrange
结束
def破坏
@category = Category.find(params [:id])
@ category.destroy
flash [:notice] =类别有被抹杀了!
redirect_to products_path
end
$ b def update
@category = Category.find(params [:id])
if @ category.update_attributes(params [ :category])
flash [:notice] =将它改为ya!
redirect_to products_path
else
flash [:alert] =类别尚未更新。
render:action => edit
end
end
def show
@category = Category.find(params [:id])
end
def index
end
def sort
params [:category] .each_with_index do | id,index |
Category.update_all({position:index + 1},{id:id})
end
end
end
Routes.rb
Jensenlocksmithing :: Application.routes。 draw do
getlog_out=> sessions#destroy,如:log_out
getlog_in=> session#new,如:log_in
获得site / home
获得site / about_us
获得site / faq
获得site / discounts
获得site / services
获得site / contact_us
获得site / admin
获得site / posts
获得categories / new_subcategory
getcategories / edit_subcategory
资源:用户
资源:会话
资源:优惠券
资源:monthly_posts
资源:类别do
collection {post:sort}
resources:children,:controller => :类别,:仅限=> [:index,:new,:create,:new_subcategory]
结束
资源:子类别
资源:产品
资源:评论
资源:faqs do
collection {post:sort}
end
root to:'site#home'
end
categories / form.html.erb
<%= form_for(@类别)do | f | %GT;
< p>
<%= f.label(:name)%>
<%= f.text_field:name%>
< / p>
< p>
<%= f.label(:parent_id)%>
<%= f.select:parent_id,nested_set_options(@ category_2_deep,@category){| i,level | #{' - '* level if level< 1}#{i.name if level <1}}%>
< / p>
< p>
<%= f.label(:position)%>
<%= f.select:position,1..category_count%>
< / p>
< p>
<%= f.submit(提交)%>
< / p>
<%end%>
看起来像nested_set正在寻找一个Array类似数组的集合 - 请参阅源代码的第32行: https://github.com/skyeagle/nested_set/blob/21a009aec86911f5581147dd22de3c5d086355bb/lib/nested_set/helper.rb#L32
...因此它越来越ActiveRecord :: Relation将其封装在[数组](第35行)中,然后尝试迭代并炸毁。
轻松修复 :首先在集合上调用 to_a
- 在您的控制器中:
@ category_2_deep = Category.with_depth_below(2).to_a
更好的解决方法:submit给维护者一个补丁,它更像Ruby,并且它看起来像一个Array,但不一定是一个。
I am using the Nested_Set gem in my code to sort Categories, Subcategories, and Products. I am trying to limit the depth/level of my nested set to no deeper then 2. Currently I am getting the error
Nested Set Error undefined method `self_and_descendants' for #<ActiveRecord::Relation:0x52c4a30>
I am trying to create a restraunt menu type style, and am going to attempt to make it drag and drop sortable.
Here is my code: Can someone browse it and help me understand this error? Thanks Category.rb
class Category < ActiveRecord::Base
acts_as_nested_set
acts_as_list :scope => :parent_id
has_many :products
scope :category, where("parent_id IS NULL")
scope :subcategories, where("parent_id IS NOT NULL")
scope :with_depth_below, lambda { |level| where(self.arel_table[:depth].lt(level)) }
end
categories_controller
class CategoriesController < ApplicationController
def new
@category = params[:id] ? Category.find(params[:id]).children.new : Category.new
@count = Category.count
end
def new_subcategory
@category = params[:id] ? Category.find(params[:id]).children.new : Category.new
@category_2_deep = Category.with_depth_below(2)
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])
@category_2deep = Category.with_depth_below(2).arrange
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 show
@category = Category.find(params[:id])
end
def index
end
def sort
params[:category].each_with_index do |id, index|
Category.update_all({position: index+1}, {id: id})
end
end
end
Routes.rb
Jensenlocksmithing::Application.routes.draw do
get "log_out" => "sessions#destroy", as: "log_out"
get "log_in" => "sessions#new", as: "log_in"
get "site/home"
get "site/about_us"
get "site/faq"
get "site/discounts"
get "site/services"
get "site/contact_us"
get "site/admin"
get "site/posts"
get "categories/new_subcategory"
get "categories/edit_subcategory"
resources :users
resources :sessions
resources :coupons
resources :monthly_posts
resources :categories do
collection { post :sort }
resources :children, :controller => :categories, :only => [:index, :new, :create, :new_subcategory]
end
resources :subcategories
resources :products
resources :reviews
resources :faqs do
collection { post :sort }
end
root to: 'site#home'
end
categories/form.html.erb
<%= form_for(@category) do |f| %>
<p>
<%= f.label(:name) %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label(:parent_id) %>
<%= f.select :parent_id, nested_set_options(@category_2_deep, @category) {|i, level| "# {'-' * level if level < 1 } #{i.name if level < 1 }" } %>
</p>
<p>
<%= f.label(:position) %>
<%= f.select :position, 1..category_count %>
</p>
<p>
<%= f.submit("Submit") %>
</p>
<% end %>
It looks like nested_set is looking for an Array not just an array-like collection - see line 32 of the source: https://github.com/skyeagle/nested_set/blob/21a009aec86911f5581147dd22de3c5d086355bb/lib/nested_set/helper.rb#L32
...hence it's getting that ActiveRecord::Relation, wrapping it in an [array] (line 35) and then trying to iterate and blowing up.
Easy fix: call to_a
on the collection first - in your controller:
@category_2_deep = Category.with_depth_below(2).to_a
Better fix: submit a patch to the maintainer that's a bit more Ruby-like and looks for it to behave like an Array, but not necessarily be one.
这篇关于Nested Set Error未定义方法`self_and_descendants'for#< ActiveRecord :: Relation:0x52c4a30>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!