How should I setup assets in Rails 3.1 to be able to show images that're created on fly? - ruby-on-rails-3.1

I've Rails 3.1 application which generates some images in 'public/scene/ticket_123/*.png' on fly. It works normally in development mode, but in production all assets should be precompiled. So I can't use files that I've generated after application started.
Setting config.assets.compile = true hasn't solve my problem. Situation is only worse since ticket number changes - so images are in different directories which are continiously created on fly too.
How should I setup assets to be able to show images that're created after an application was started?

I had the same problem. I only found a work around by copying all my images into "public/images" and changed all the links to the new path.
That worked for me for the moment. I wait until somebody comes up with a better idea.
I hope that helps.

If found solution.
# In view I wrote
<img src=<%= mycontroller_image_get_path :filename=>file_name %> >
# In controller I created GET action
def image_get
send_file params[:filename], :disposition => 'inline', :type => 'image/png'
end
But you should care that file you're trying to send is in "#{Rails.root}/public" directory otherwise send_file says it can't found the file. (May be it is not necessary in /public but in Rails.root anyway). To change this behavior it can be useful to read this topic Can I use send_file to send a file on a drive other than the Rails.root drive?

Related

Rails File.exist? yields false when file is present

I've found a few posts here regarding File.exists? in a Rails app but trying the solutions have not helped, I'm fairly new so I must be doing something dumb.
I'm using:
Rails 3.2.11
Ruby 1.9.3
Paperclip for the file mentioned below
ActiveAdmin to upload the file mentioned below
Working in development environment
Assets not precompiled
I have a model "style" and it has an image attachment, I can render the image with
<%= image_tag(#style.style_image) %>
and it works just fine.
In short, I want to check if the file image is actually there in the folder it should be in - I don't want to use #style.style_image.present? for checking images because that just checks the db record. I want to use File.exist? to see if there's actually a file for #style.style_image.
So in my view file, I have the code
<% if File.exist?(#style.style_image.url) %>
The image exists.
<% else %>
The image is not here.
<% end %>
And it always prints "the image is not here" when I load the page. Directly below I am displaying my image using image_tag, so I know for fact that the image is there.
I've also tried
<% if File.exist?(Rails.root + #style.style_image.url) %>
with no luck. I also tried using FileTest.exist?, FileTest.exists?, and File.exists? but none will tell me true when the image is definitely there.
Is there something I'm missing? Any guidance would be appreciated very much. I'm only a few months into Ruby and Rails so I'm probably missing something dumb.
I think you want #style.style_image.path instead of .url.
Print it out to be sure.
Any time you are dealing with web URLs and files on disk, you have to be careful which "path" you are using, and keep it straight whether you are telling your code to where to find the file, or a browser how to request that same file.
The web server hides the OS's file structure from the user/browser for lots of reasons, with security being a very high one. For instance, URLs are relative to the server, not the root of the drive.
What you ran into is very common and odds are really good that everyone who is working with programming for the web has, or will, run into the same thing, probably several times.

How to turn my rails app into static content?

My rails app fetches a bunch of xml feeds once a day, loads them into the db and then displays them in aggregate. I'm thinking that I can save on server memory if I just output the pages as static files and let them be served directly by the front-end server (nginx in my case). I asked in an IRC room and was told to not use rails and create the files using rake tasks. However, I'm wondering what the easiest way would be to go about doing this. Layout, asset files and content are in different places in rails obviously, so I guess I would need to combine the layout and content and then insert the css/javascript.
Any thoughts/ideas are welcome.
[Solved]
I ended up using the examples from render_to_string from a rake task and made some tweaks to get the following code inside my rake task:
views_path = Rails.root.to_s + "/app/views"
av = ActionView::Base.new(views_path)
av.class_eval do
include ApplicationHelper
end
products = Product.all
a = av.render(:template => "products/show", :layout => "layouts/application", :locals => { :#products => products } )
This then renders both the template and the layout, and allows the use of the #products instance variable inside the template just as you would if you were using a controller.
Then I just need to write the output of the render to a file.
For a task like this you can use Rails' built in caching mechanisms.
There is another stack overflow post which shows some example code of how to build code to write that cache manually from something like a rake task.
Perhaps middleman or jekyll could be used?
I've only used middleman, but you could use a rake task and support script to get the latest xml feeds and stick that into middlemans data dir (i.e. data/feeds.yml), then use your existing layouts to render that yaml file. Middleman and rails share a lot of similar tech for rendering etc.
You'd have to modify your layouts a little bit.
You could probably find gems to replace yaml with something else if you wanted.

Sinatra cache control is not working

This is what I have done to my server
set :static_cache_control, [:public, {:max_age => 604800}]
However, when I use firebug I still see 0 max-age. And I'm using Sinatra Assets Pack http://ricostacruz.com/sinatra-assetpack/
I'm not sure if they conflict each other?
Thanks a lot.
Which file you add max-age header?
If it's JavaScript or CSS file, please try to build files with Sinatra-assetpack.
Files built are located in under 'public' directory.
Please see the following, written how to build.
http://ricostacruz.com/sinatra-assetpack/#need_to_build_the_files

PDFkit rails3.1 and development env

My Rails 3.1 app is using PDFkit to render specific pages, and I'm running into (what seems like) a common problem with where trying to generate the pdf is causing the process to hang.
I found this solution here on stackoverflow: rails 3 and PDFkit. Where I add a config.threadsafe! entry in my development.rb file and this works BUT it requires that for every change anywhere in the app I have to stop and restart my server to see my changes. NOT acceptable from a workflow - I'm currently setting up the styling for the PDF pages, and it's painfully slow process having to do this.
I also found the same issue reported here: https://github.com/jdpace/PDFKit/issues/110, and the issue points to this workaround: http://jguimont.com/post/2627758108/pdfkit-and-its-middleware-on-heroku.
ActionController::Base.asset_host = Proc.new { |source, request|
if request.env["REQUEST_PATH"].include? ".pdf"
"file://#{Rails.root.join('public')}"
else
"#{request.protocol}#{request.host_with_port}"
end
}
This removes the need to restart the change, BUT now when I load the pdf it's without the styles rendered from the asset pipeline because it's taking the assets from the public directory. I think I could work with this solution if I could know how to create the stylesheets for the pdf templates in the public folder. IS anyone developing with PDFKit and Rails3.1 where this is all working in sync?
Any help would be greatly appreciated!
Thanks!
Tony
Here is the setup I am using:
I run a second instance of rails server with rails server -p 3001 -e test which will handle my assets for the PDF. The server will print the assets requests as they come in, so I can check that everything works as expected.
I use the following asset_host in my config/environments/development file:
config.action_controller.asset_host = ->(source, request = nil){
"http://localhost:3001" if request && request.env['REQUEST_PATH'].include?(".pdf")
}
If you are using Pow, you can use multiple workers. Add this to your ~/.powconfig
export POW_WORKERS=3
(taken from Pow manual)
There's a problem with pdfkit in Rails 3.1. See my answer to this related question:
pdfkit does not style pdfs

Telerik CDN Support

According to Telerik:
To distribute your web asset group via content delivery network you should use the ContentDeliveryNetworkUrl() method:
<%= Html.Telerik().ScriptRegistrar().Scripts(scripts =>
scripts.AddGroup("CommonScript", group =>
group.Add("~/Scripts/Core.js")
.Add("~/Scripts/Stuff.js")
.Combined(true)
.CacheDurationInDays(365)
.Compress(true)
.ContentDeliveryNetworkUrl("http://mycdn.com/CommonScript.js")
)
I'm confused by this, specifically:
ContentDeliveryNetworkUrl("http://mycdn.com/CommonScript.js")
How does this file get created on the CDN? I assume Core.js and Stuff.js get combined, cached, and compressed then uploaded to my CDN automatically? Or is CommonScript.js another JS file that get's added to the combined script? If so, then the combined script gets served locally still, and not from the CDN?
Telerik say VERY VERY little about how all this work.
Any help is greatly appreciated.
Matt
You need to upload the combined file by yourself. The ContentDeliveryNetworkUrl just tells the script registrar to output that value instead of core.js and stuff.js.

Resources