Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在rails中高效地获取父对象_Ruby On Rails_Ruby On Rails 3 - Fatal编程技术网

Ruby on rails 在rails中高效地获取父对象

Ruby on rails 在rails中高效地获取父对象,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,我正在写一个图像库。 库中的图像属于项目。每个项目都可以有一个父项目。 例如project1>project2>project3>image1 为了允许管理员使用FTP,我希望文件有“漂亮”的路径。 缩略图和预览存储在ROOT/previews/和ROOT/Thumbnails/中,而图像存储在ROOT/images///…/ 管理员可以简单地将图像上传到正确的文件夹,应用程序将发现它们并处理所有事情 这当然会导致在获取图像路径时必须获取所有父对象的问题。目前,这意味着首先获取图像,然后是项目,

我正在写一个图像库。
库中的图像属于项目。每个项目都可以有一个父项目。
例如
project1>project2>project3>image1

为了允许管理员使用FTP,我希望文件有“漂亮”的路径。
缩略图和预览存储在
ROOT/previews/
ROOT/Thumbnails/
中,而图像存储在
ROOT/images///…/

管理员可以简单地将图像上传到正确的文件夹,应用程序将发现它们并处理所有事情

这当然会导致在获取图像路径时必须获取所有父对象的问题。目前,这意味着首先获取图像,然后是项目,然后是父项目,依此类推。
如果总是一个祖先(嵌套级别),那么问题很容易解决,问题出在0或更多

我不希望项目嵌套得很深,但我仍然担心每个请求有很多查询是不好的

我有什么办法可以避免这种情况吗?也许一次就能拿到所有的东西?
也许我应该跳过FTP上传,只允许从UI拖放

也许我担心的太多了,我只是通过索引字段来约束查询


我的
schema.rb
当前看起来如下:

ActiveRecord::Schema.define(:version => 20110827230616) do

  create_table "images", :force => true do |t|
    t.string   "name"
    t.string   "filename"
    t.text     "info"
    t.integer  "project_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "images", ["project_id", "filename"], :name => "index_images_on_project_id_and_filename", :unique => true

  create_table "projects", :force => true do |t|
    t.string   "name"
    t.text     "info"
    t.string   "dates"
    t.integer  "parent_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "projects", ["parent_id", "name"], :name => "index_projects_on_parent_id_and_name", :unique => true

end
Started GET "/images/1" for 127.0.0.1 at Sat Sep 03 10:23:30 -0700 2011
  Processing by ImagesController#show as HTML
  Parameters: {"id"=>"1"}
  Image Load (0.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = ? LIMIT 1  [["id", "1"]]
  Project Load (0.2ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = 2 LIMIT 1
  Project Load (0.2ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = 1 LIMIT 1
  Project Load (0.1ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" IS NULL LIMIT 1
image.rb

class Image < ActiveRecord::Base
  belongs_to :project

  # Validation
  validates_presence_of :project_id, :filename

  attr_readonly :filename

  def path
    if not self.project_id or not self.project
      raise "Called path on an image without a project"
    end
    return File.join(self.project.path, self.filename)
  end

  def thumbnail_path
    raise "Called thumbnail_path on an image without an id" unless self.id
    return File.join(Rails.application.config.thumbnail_directory, self.id.to_s)
  end

  def preview_path
    raise "Called preview_path on an image without an id" unless self.id
    return File.join(Rails.application.config.preview_directory, self.id.to_s)
  end

  def exists?
    if not File.file? self.path
      return false
    end

    return true
  end
end
class Project < ActiveRecord::Base
  belongs_to :parent, :class_name => 'Project'
  has_many   :children, :class_name => 'Project', 
             :dependent => :destroy, :foreign_key => 'parent_id'
  has_many   :images, :dependent => :destroy

  def safe_name
    return self.name.downcase.gsub(/\s/, '-').gsub(/[^a-z0-9-]/, '_')
  end

  def path
    tmp = self
    parents = []
    while tmp
      parents.insert(0, tmp.safe_name)
      tmp = tmp.parent
    end

    return File.join(Rails.application.config.image_directory, parents)
  end
end
请求示例如下所示:

ActiveRecord::Schema.define(:version => 20110827230616) do

  create_table "images", :force => true do |t|
    t.string   "name"
    t.string   "filename"
    t.text     "info"
    t.integer  "project_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "images", ["project_id", "filename"], :name => "index_images_on_project_id_and_filename", :unique => true

  create_table "projects", :force => true do |t|
    t.string   "name"
    t.text     "info"
    t.string   "dates"
    t.integer  "parent_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "projects", ["parent_id", "name"], :name => "index_projects_on_parent_id_and_name", :unique => true

end
Started GET "/images/1" for 127.0.0.1 at Sat Sep 03 10:23:30 -0700 2011
  Processing by ImagesController#show as HTML
  Parameters: {"id"=>"1"}
  Image Load (0.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = ? LIMIT 1  [["id", "1"]]
  Project Load (0.2ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = 2 LIMIT 1
  Project Load (0.2ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = 1 LIMIT 1
  Project Load (0.1ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" IS NULL LIMIT 1

可以使用嵌套集模型来存储项目。使用它,您可以简单地获取项目,然后在一个查询中获取项目的所有父项

维基百科关于嵌套集:

用于嵌套集的Rails插件:

发布了
schema.rb
,是否也要实现?这是一个相当空的ATM机(大部分都有
:属于
)如果你有
多个
有一个
关联,那也不错。我不太明白的是,你怎么能有“0个或更多”父母有
属于
关联。你是说0还是1?我是说,0个或更多的祖先,但是的,它只是0或1个父母。但该父级可以有0个或1个父级,以此类推。啊,好吧,0个或更多与嵌套级别有关。我看到插入非常慢,不是我期望有很多插入,但仍然如此。是的,这是缺点。不过,“非常慢”是相对的,除非你期望有很多很多项目,否则我怀疑这会是一个问题。好吧,我希望它是可伸缩的(当然不是facebook的大小,但仍然),多少是“很多”?我不确定;几千?您可以相当快地进行设置,为自己播种大量项目,并运行一些基准测试,以查看性能何时开始真正下降。我认为插入可能需要很长时间,因为您需要在每次插入/删除时更新整个表