使用Closure_tree宝石,而不是真棒组嵌套 [英] Using Closure_tree gem instead of Awesome nested set

查看:202
本文介绍了使用Closure_tree宝石,而不是真棒组嵌套的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我跟着链接成立closure_tag宝石。

当我试图用closure_tree语法按以下方式(newStructure.find_or_create_by_path(母公司),而不是newStructure.move_to_child_of(母公司))......得到了以下错误:

无法大规模分配保护的属性:祖先,后裔,世代

这是使用newStructure.find_or_create_by_path(父)的正确方法是什么?

 高清self.import(路径)

    newStructure = FileOrFolder.find(:第一,:条件=> [?FULLPATH =路径])
    如果newStructure
      返回newStructure
    结束

    newStructure = FileOrFolder.new
    newStructure.fullpath =路径
    pathbits = path.split('/')
    newStructure.name = pathbits.last
    newStructure.save




    parentpath = path.sub(/#{Regexp.escape(pathbits.last)} $ /,'')
        如果parentpath.length> 1
          parentpath.sub!(/ \ / $ /,'')
          父= FileOrFolder.find(:第一,:条件=> [?FULLPATH =,parentpath])
          除非父母
            父= FileOrFolder.import(parentpath)
          结束
          #newStructure.move_to_child_of(父);
          ** newStructure.find_or_create_by_path(父)**
        结束
        newStructure.save
        返回newStructure

      结束






数据库表的样子:

MySQL的> SELECT * FROM testdb7.file_or_folders限制10;
+------+-----------+------+------+----------+------------------------+---------------------+---------------------+
| ID | PARENT_ID | LFT | RGT | FULLPATH |名称| created_at |的updated_at |
+------+-----------+------+------+----------+------------------------+---------------------+---------------------+
| 6901 | NULL | NULL | NULL | NULL | | 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6902 | 6901 | NULL | NULL | NULL | devel软件包| 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6903 | 6902 | NULL | NULL | NULL | B控制| 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6904 | 6903 | NULL | NULL | NULL |完美| 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6905 | 6904 | NULL | NULL | NULL | MATLAB | 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6906 | 6905 | NULL | NULL | NULL |测试| 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6907 | 6906 | NULL | NULL | NULL |烟| 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6908 | 6907 | NULL | NULL | NULL | Control_System_Toolbox | 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6909 | 6908 | NULL | NULL | NULL | tsmoke_are.m | 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
| 6910 | 6908 | NULL | NULL | NULL | tsmoke_bode.m | 2013年6月25日18点49分04秒| 2013年6月25日18点49分04秒|
+------+-----------+------+------+----------+------------------------+---------------------+---------------------+



FileOrFolder负载(14560.8ms)选择`file_or_folders`。* FROM`file_or_folders` INNER JOIN`file_or_folder_hierarchies`开`file_or_folders`.`id` =`file_or_folder_hierarchies`.`descendant_id` INNER JOIN(
 选择ancestor_id
 FROM`file_or_folder_hierarchies`
 GROUP BY 1
 HAVING MAX(`file_or_folder_hierarchies`.generations)= 0
 )AS叶子(`file_or_folders`.id = leaves.ancestor_id),其中`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`开`file_or_folders`.`id` =`file_or_folder_hierarchies`.`descendant_id` INNER JOIN(
 选择ancestor_id
 FROM`file_or_folder_hierarchies`
 GROUP BY 1
 HAVING MAX(`file_or_folder_hierarchies`.generations)= 0
 )AS叶子(`file_or_folders`.id = leaves.ancestor_id),其中`file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY`file_or_folder_hierarchies`.generations ASC
EXPLAIN为:SELECT`file_or_folders` * FROM`file_or_folders` INNER JOIN`file_or_folder_hierarchies`开`file_or_folders`.`id` =`file_or_folder_hierarchies`.`descendant_id` INNER JOIN(
            选择ancestor_id
            FROM`file_or_folder_hierarchies`
            GROUP BY 1
            HAVING MAX(`file_or_folder_hierarchies`.generations)= 0
          )AS叶子(`file_or_folders`.id = leaves.ancestor_id),其中`file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY`file_or_folder_hierarchies`.generations ASC
+----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+
| ID | SELECT_TYPE |表|键入| possible_keys |关键| key_len |裁判|行|额外|
+----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+
| 1 | PRIMARY | file_or_folder_hierarchies |裁判| index_file_or_folders_on_ans_des,index_file_or_folder_hierarchies_on_descendant_id | index_file_or_folders_on_ans_des | 4 |常量| 15 |使用临时;使用文件排序|
| 1 | PRIMARY | < D​​erived2的> | ALL | NULL | NULL | NULL | NULL | 104704 |用在哪里;使用连接缓冲|
| 1 | PRIMARY | file_or_folders | eq_ref | PRIMARY | PRIMARY | 4 | leaves.ancestor_id | 1 |使用其中|
| 2 |衍生| file_or_folder_hierarchies |指数| NULL | index_file_or_folders_on_ans_des | 8 | NULL | 1340096 | |
+----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+
 

解决方案

我closure_tree的作者。 4.2.3是它的方式与attr_accessible修复。我只是在等待特拉维斯完成测试。

它看起来像你的整个进口方法可以替换该行:

 #假定该路径是一个字符串,它看起来像这样:在/ usr / local / bin目录/红宝石
高清输入(路)
  FileOrFolder.find_or_create_by_path(path.split(/))
结束
 

此假设你有这样的FileOrFolder设置:

 类FileOrFolder<的ActiveRecord :: Base的
  acts_as_tree
  before_create:set_fullpath
  高清set_fullpath
    如果根?
      self.fullpath =/#{名}
    其他
      self.fullpath =/#{parent.ancestry_path.join("/")}/#{name}
    结束
  结束
结束
 

请看看在规范目录。你会发现的的其他例子。

Hi I followed the link to set up closure_tag gem.

When i tried to use closure_tree syntax in the following way (newStructure.find_or_create_by_path(parent) instead of newStructure.move_to_child_of(parent)) ... got the following error :

"Can't mass-assign protected attributes: ancestor, descendant, generations"

is this the correct way of using 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     | <derived2>                 | 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 |                                 |
+----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+

解决方案

I'm the author of closure_tree. 4.2.3 is on it's way with the fix for attr_accessible. I'm just waiting for Travis to finish testing it.

It looks like your whole import method could be replaced with this line:

# 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

This assumes you have this FileOrFolder setup:

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

Please take a look at the spec directory. You'll find tons of other examples.

这篇关于使用Closure_tree宝石,而不是真棒组嵌套的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆