对于我已部署到heroku的rails应用程序,我需要为不同的用户编译不同的样式表,然后将它们上传到Amazon S3。我创建了一个定义了几个变量(主要是颜色)的sass文件,然后编译该文件并暂时将其保存到tmp目录中。从那里,我立即将编译的css文件保存到S3。以下是我用来执行此操作的代码:
class StyleCompiler
def initialize stylesheet
# Load the stylesheet into an instance variable
@stylesheet = stylesheet
# Get the type of owner of the stylesheet
@type = @stylesheet.styleable_type
# Get the id of the owner
@id = @stylesheet.styleable_id
# Create necessary directories if they dont exist
if !Dir.exists? Rails.root.join("tmp")
Dir.mkdir Rails.root.join("tmp", "stylesheets")
end
if !Dir.exists? Rails.root.join("tmp", "stylesheets")
Dir.mkdir Rails.root.join("tmp", "stylesheets")
end
if !Dir.exists? Rails.root.join("tmp", "stylesheets", "#{@type}_#{@id}")
Dir.mkdir Rails.root.join("tmp", "stylesheets", "#{@type}_#{@id}")
end
end
def compile_erb
# Path to the erb stylesheet
@erb_path = File.read(File.join(Rails.root, 'lib', 'assets', 'styles.scss.erb'))
# Compile erb file
@definitions = ERB.new(@erb_path).result(binding)
end
def save_to_assets
File.open(Rails.root.join("app", "assets", "stylesheets", "definitions.css.scss"), 'w') {|f| f.write @definitions}
end
def compile_sass
# Append the necessary sass import to the definitons file
@manifest = @definitions += "\n\n@import 'include';"
# Write Stylesheet to temp location as a sass file
@manifest_name = "manifest_#{Time.now.to_i.to_s}.scss"
@temp_path = Rails.root.join("tmp", "stylesheets", "#{@type}_#{@id}", @manifest_name)
File.open(@temp_path, 'w') {|f| f.write @manifest}
# Copy the default rails sprocket environment
sprockets = Rails.application.assets.dup
puts sprockets.paths
# Find the desired manifest file that was just created
asset = Rails.application.assets.find_asset "#{@type}_#{@id}/#{@manifest_name}"
# Write the compiled css file to a temporary location
@compiled_name = "compiled_#{Time.now.to_i.to_s}.css"
asset.write_to Rails.root.join("tmp", "stylesheets", "#{@type}_#{@id}", @compiled_name)
end
def upload
# Configure S3 variable
s3 = AWS::S3.new(
:access_key_id => ENV['S3_ACCESS_KEY'],
:secret_access_key => ENV['S3_SECRET_KEY']
)
# Get Bucket
bucket = s3.buckets['watsco-cdn']
# Delete the old css file
if @stylesheet.url != nil
old_obj = bucket.objects[@stylesheet.url.split(".net/").last]
old_obj.delete
end
# Upload
@stylesheet_name = "stylesheet_" + Time.now.to_i.to_s
obj = bucket.objects["#{@type}_#{@id}/#{@stylesheet_name}.css"]
obj.write(:file => Rails.root.join("tmp", "stylesheets", "#{@type}_#{@id}", @compiled_name), :acl => :public_read)
# Save new url to stylesheets
@stylesheet.url = "http://ddyjn572xhp9e.cloudfront.net/#{@type}_#{@id}/#{@stylesheet_name}.css"
@stylesheet.save!
# Delete Temp Files
File.delete Rails.root.join("tmp", "stylesheets", "#{@type}_#{@id}", @compiled_name)
File.delete Rails.root.join("tmp", "stylesheets", "#{@type}_#{@id}", @manifest_name)
end
端
一切都在本地工作正常,但在heroku上我一直收到这个错误:
NoMethodError(未定义的方法write_to' for nil:NilClass):
2014-07-27T20:39:44.994773+00:00 app[web.1]: lib/StyleCompiler.rb:64:in
compile_sass'
2014-07-27T20:39:44.994774 + 00:00 app [web.1]:app / models / dealer.rb:55:in compile_stylesheet'
2014-07-27T20:39:44.994775+00:00 app[web.1]: app/controllers/dealers_controller.rb:44:in
update_color'
一旦我部署应用程序并运行heroku重启,它实际上是有效的。它很奇怪,因为我已经验证了我正在寻找的资产文件存在并且在目录中,但链轮似乎没有看到它,因为我在运行asset_find时得到了nil。任何解释都会非常感激,因为我不知道为什么会发生这种情况。