【发布时间】:2015-04-19 13:43:00
【问题描述】:
我正在使用 Rails 应用程序,该应用程序当前正在创建或保存 User 类之前和之后创建类。我在这条路径上遇到的问题是一个类正在从一个非常大的 S3 AWS 存储桶中读取,我需要将超过 7,000 个对象添加到我们的数据库中。整个过程大约需要 32 毫秒来创建对象,将这些对象添加到 Batch 数据库需要 2911 毫秒。 我将其添加到我们的数据库而不是简单地读取 AWS 存储桶的原因是 1) 为这些对象添加属性 2) 对象可用于 iPhone 应用程序
我很想找到一种方法,在 Rails 应用程序完成加载或在后台运行代码之前,将该存储桶读取并创建到数据库中。
这是我的 Batch.rb 代码:
class Batch < ActiveRecord::Base
serialize :folder, JSON
has_many :tops
has_many :bottoms
def access_bucket
AwsAccess.new('curateanalytics', [], "", {}).sort_through_bucket
end
class AwsAccess
def initialize(bucket_name, array, current, obj)
@bucket_name = bucket_name
@array = array
@current = current
@obj = obj
@newfolder
@newbatch
@newurl
end
def access_bucket
return AWS::S3.new.buckets[@bucket_name]
end
def sort_through_bucket
access_bucket.objects.each do |obj|
if obj_is_swipe_batch?(obj)
create_new_instances(obj)
if !obj_contains_key?
add_newfolder_key
end
if !current_equals_batch?
@current = @newbatch
if array_not_array?
@obj[@newfolder] << @array
end
end
if Properties.new(@newurl).find_properties[:main_category] == "Bottoms"
@bottom = Bottoms.create({:batch_folder => @newfolder, :batch_number => @newbatch , :file_name => @newurl.split("/").last.gsub("%26","&"), :url => @newurl, :properties => Properties.new(@newurl).find_properties})
end
if Properties.new(@newurl).find_properties[:main_category] == "Tops"
@top = Tops.create({:batch_folder => @newfolder, :batch_number => @newbatch, :file_name => @newurl.split("/").last.gsub("%26","&"), :url => @newurl, :properties => Properties.new(@newurl).find_properties})
end
end
end
end
def obj_is_swipe_batch?(obj)
return ((obj.key =~ /swipe batches/) && (obj.key =~ /jpg/))
end
def create_new_instances(obj)
@newfolder = obj.key.split("/")[1]
@newbatch = obj.key.split("/")[obj.key.split("/").length-2]
@newurl = "https://s3.amazonaws.com/curateanalytics/" + obj.key.gsub('&', '%26').gsub('swipe ', 'swipe+')
end
def obj_contains_key?
@obj.key?(@newfolder)
end
def add_newfolder_key
@obj.merge!(@newfolder => [])
end
def current_equals_batch?
@current == @newbatch
end
def array_not_array?
@array != []
end
end
class Properties
def initialize(bucket_url)
@bucket_url = bucket_url
@hash = {}
end
def find_properties
read_json
parse_json
parse_main
parse_sub
return @hash
end
def read_json
@json = JSON.parse(File.read(File.join(Rails.root, 'public', 'DatabaseArray.json')))
end
def parse_json
@json.each do |main|
@main = main
end
end
def parse_main
@main.each do |sub|
@sub = sub
end
end
def parse_sub
@sub.gsub("\"","")[1..-2].split(",").each do |properties|
@property = properties.split(":")
is_everything
end
end
def is_URL?
@property.first == "URL"
end
def is_File_Name?
@property.first == "File_Name"
end
def is_Main?
@property.second == "{Main_Category"
end
def is_everything
if !is_URL? && !is_File_Name? && is_Main?
hash_merge(@property.second.gsub!("{",""),@property.last)
elsif !is_URL? && !is_File_Name?
hash_merge(@property.first,@property.last)
end
end
def hash_merge(name, property)
@hash.merge!(name.parameterize.underscore.to_sym => property)
end
end
end
到目前为止,我已经考虑将此代码作为initializer。我可以访问 /config/initializer/batch.rb 文件,它看起来与使用 binding.pry 的这个 batch.rb 文件完全相同,但代码永远不会运行。
【问题讨论】:
标签: ruby-on-rails amazon-s3 initializer