2012-12-13 82 views
0

查找模块返回的文件数我有一个调用一个find_photos方法,传递一个查询字符串(文件名)红宝石,限制与每个请求

class BrandingPhoto < ActiveRecord::Base 

    def self.find_photos(query) 
    require "find" 

    found_photos = [] 

    Find.find("u_photos/photo_browse/photos/") do |img_path| 
     # break off just the filename from full path 
     img = img_path.split('/').last 

     if query.blank? || query.empty? 
     # if query is blank, they submitted the form with browse all- return all photos 
      found_photos << img 
     else 
     # otherwise see if the file includes their query and return it 
      found_photos << img if img.include?(query) 
     end 
    end 

    found_photos.empty? ? "no results found" : found_photos 
    end 
end 

此控制器只是搜索的目录全照片 - 没有桌子支持这一点。

理想情况下,我希望能够将find_photos返回的结果数量限制在10-15左右,然后根据需要获取接下来的10-15个结果。

我在想这样做的代码可能涉及循环10次并抓取这些文件 - 将最后一个文件名存储在一个变量中或作为参数,然后将该变量发送回该方法,告诉它继续从该文件名搜索。

这假定文件每次都以相同的顺序循环,并且没有更简单的方法来完成此操作。

如果有任何建议,我很乐意听到他们/看到你如何做到这一点的一些例子。

谢谢。

+0

你能为你正在寻找的行为写一些测试/规格吗?你想怎么称呼这个方法?你如何继续从你离开的地方?它有助于在规范中设计API,然后从那里开始工作。也可以看看Ruby的[Enumarable](http://rubydoc.info/stdlib/core/Enumerable)API,以了解Ruby本身已经可以实现的功能。我觉得你可以用Enumerable中的方法将代码细化到一行。 – iain

+0

我想不出一个简单的方法来做到这一点。你可能想要在你自己的类中包装这个find来记忆目录列表并实现分页。您可以记忆一段时间,或实现一种注册新图像的方式。如果你需要做这样的事情,你最好将图像元数据存储在数据库中。你可能想看看图像管理的[Dragonfly](https://github.com/markevans/dragonfly)和[Paperclip](https://github.com/thoughtbot/paperclip)gems。 –

回答

0

想到这个问题的第一件事就是在退出循环之后将阵列向下切。这对于大量的文件来说效果不佳,但不同的解决方案可能是为数组大小添加一个中断。 break if found_photos.length > 10循环内

0

要做你想做的事情并不难,但你需要考虑如何处理在页面加载,UTF-8或Unicode字符的文件名之间添加或删除的条目,以及嵌入/父目录。

这是依据老学校代码,你在说什么:

require 'erb' 
require 'sinatra' 

get '/list_photos' do 

    dir = params[ :dir ] 
    offset = params[ :offset ].to_i 
    num = params[ :num ].to_i 

    files = Dir.entries(dir).reject{ |fn| fn[/^\./] || File.directory?(File.join(dir, fn)) } 
    total_files = files.size 

    prev_a = next_a = '' 

    if (offset > 0) 
    prev_a = "<a href='/list_photos?dir=#{ dir }&num=#{ num }&offset=#{ [ 0, offset - num ].max }'>&lt;&lt; Previous</a>" 
    end 

    if (offset < total_files) 
    next_a = "<a href='/list_photos?dir=#{ dir }&num=#{ num }&offset=#{ [ total_files, offset + num ].min }'>Next &gt;&gt;</a>" 
    end 

    files_to_display = files[offset, num] 

    template = ERB.new <<EOF 
<html> 
    <head></head> 
    <body> 
    <table> 
    <% files_to_display.each do |f| %> 
     <tr><td><%= f %></td></tr> 
    <% end %> 
    </table> 
    <%= prev_a %> | <%= total_files %> files | <%= next_a %> 
    </body> 
</html> 
EOF 

    content_type 'text/html' 
    template.result(binding) 

end 

这是一个有点西纳特拉服务器,因此它保存为test.rb,并使用在命令行中运行:

ruby test.rb 

在浏览器连接到正在运行的服务器西纳特拉使用URL,如:

http://hostname:4567/list_photos?dir=/path/to/image/files&num=10&offset=0 

为了方便,我使用Sinatra,但例程的内容是您想要的基础。如何将其转换为Rails术语作为读者的练习。