使用Closure_tree gem而不是Awesome嵌套集

嗨,我按照链接设置了closure_tag gem。

当我尝试以下列方式使用closure_tree语法时(newStructure.find_or_create_by_path(parent)而不是newStructure.move_to_child_of(parent))…得到以下错误:

“不能大规模分配受保护的属性:祖先,后代,世代”

这是使用newStructure.find_or_create_by_path(parent)的正确方法吗?

def self.import(path) newStructure = FileOrFolder.find(:first, :conditions=>["fullpath = ?", path]) if newStructure return newStructure end newStructure = FileOrFolder.new newStructure.fullpath = path pathbits = path.split('/') newStructure.name = pathbits.last newStructure.save parentpath = path.sub(/#{Regexp.escape(pathbits.last)}$/, '') if parentpath.length > 1 parentpath.sub!(/\/$/,'') parent = FileOrFolder.find(:first, :conditions=>["fullpath = ?", parentpath]) unless parent parent = FileOrFolder.import(parentpath) end #newStructure.move_to_child_of(parent); **newStructure.find_or_create_by_path(parent);** end newStructure.save return newStructure end database table looks like : mysql> select * from testdb7.file_or_folders limit 10; +------+-----------+------+------+----------+------------------------+---------------------+---------------------+ | id | parent_id | lft | rgt | fullpath | name | created_at | updated_at | +------+-----------+------+------+----------+------------------------+---------------------+---------------------+ | 6901 | NULL | NULL | NULL | NULL | | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6902 | 6901 | NULL | NULL | NULL | devel | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6903 | 6902 | NULL | NULL | NULL | Bcontrol | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6904 | 6903 | NULL | NULL | NULL | perfect | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6905 | 6904 | NULL | NULL | NULL | matlab | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6906 | 6905 | NULL | NULL | NULL | test | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6907 | 6906 | NULL | NULL | NULL | smoke | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6908 | 6907 | NULL | NULL | NULL | Control_System_Toolbox | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6909 | 6908 | NULL | NULL | NULL | tsmoke_are.m | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6910 | 6908 | NULL | NULL | NULL | tsmoke_bode.m | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | +------+-----------+------+------+----------+------------------------+---------------------+---------------------+ FileOrFolder Load (14560.8ms) SELECT `file_or_folders`.* FROM `file_or_folders` INNER JOIN `file_or_folder_hierarchies` ON `file_or_folders`.`id` = `file_or_folder_hierarchies`.`descendant_id` INNER JOIN ( SELECT ancestor_id FROM `file_or_folder_hierarchies` GROUP BY 1 HAVING MAX(`file_or_folder_hierarchies`.generations) = 0 ) AS leaves ON (`file_or_folders`.id = leaves.ancestor_id) WHERE `file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY `file_or_folder_hierarchies`.generations asc EXPLAIN (13343.7ms) EXPLAIN SELECT `file_or_folders`.* FROM `file_or_folders` INNER JOIN `file_or_folder_hierarchies` ON `file_or_folders`.`id` = `file_or_folder_hierarchies`.`descendant_id` INNER JOIN ( SELECT ancestor_id FROM `file_or_folder_hierarchies` GROUP BY 1 HAVING MAX(`file_or_folder_hierarchies`.generations) = 0 ) AS leaves ON (`file_or_folders`.id = leaves.ancestor_id) WHERE `file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY `file_or_folder_hierarchies`.generations asc EXPLAIN for: SELECT `file_or_folders`.* FROM `file_or_folders` INNER JOIN `file_or_folder_hierarchies` ON `file_or_folders`.`id` = `file_or_folder_hierarchies`.`descendant_id` INNER JOIN ( SELECT ancestor_id FROM `file_or_folder_hierarchies` GROUP BY 1 HAVING MAX(`file_or_folder_hierarchies`.generations) = 0 ) AS leaves ON (`file_or_folders`.id = leaves.ancestor_id) WHERE `file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY `file_or_folder_hierarchies`.generations asc +----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+ | 1 | PRIMARY | file_or_folder_hierarchies | ref | index_file_or_folders_on_ans_des,index_file_or_folder_hierarchies_on_descendant_id | index_file_or_folders_on_ans_des | 4 | const | 15 | Using temporary; Using filesort | | 1 | PRIMARY |  | ALL | NULL | NULL | NULL | NULL | 104704 | Using where; Using join buffer | | 1 | PRIMARY | file_or_folders | eq_ref | PRIMARY | PRIMARY | 4 | leaves.ancestor_id | 1 | Using where | | 2 | DERIVED | file_or_folder_hierarchies | index | NULL | index_file_or_folders_on_ans_des | 8 | NULL | 1340096 | | +----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+ 

我是closure_tree的作者。 4.2.3正在修复attr_accessible。 我只是在等Travis完成测试。

看起来您的整个import方法可以替换为此行:

 # Assumes that path is a string that looks like this: "/usr/local/bin/ruby" def import(path) FileOrFolder.find_or_create_by_path(path.split("/")) end 

这假设你有这个FileOrFolder设置:

 class FileOrFolder < ActiveRecord::Base acts_as_tree before_create :set_fullpath def set_fullpath if root? self.fullpath = "/#{name}" else self.fullpath = "/#{parent.ancestry_path.join("/")}/#{name}" end end end 

请查看spec目录。 你会发现很多其他的例子。