Rails 5 app. Asset pipelining and precompilation with heroku not showing up images from js.jsx files - asset-pipeline

I am almost done with upgrading my Rails3 app to Rails5; But I am facing a problem with assets pipelining and precompiling. We're using cdn as asset host.Now, What happens is that when I set config.assets.precompile to false in staging environment, the app doesn't load images from js.jsx files. At other places, the app is fetching the static assets (js,css,images) from the asset_host link that I've provided. But in some specific javascript files, The images is being pointed out to my app's domain like app.my_domain.com/assets/my_image.png,And it is giving 404 not found error.
In javascript, the code is something like
return (
<img src="/assets/my_image.png"></img>
)
Since this is a js file, I cannot use asset_path helper method here.
How to resolve this issue ?
PS: setting config.assets.precompile to true loads the image from app.my_domain.com/assets/my_image.png, but that's not what I want because of this. config.assets.compile=true in Rails production, why not?
Any help with this is highly appreciated. Thanks in advance.

I found an answer after some research. I changed the name of the file to js.jsx.erb and accordingly used asset_path helper method which rails provide.
return (
<img src = "asset_path 'my_image.png'"/>
)
It works.

Related

trying to rebuild a Reddit Rails App from two years ago (User Agent & BootStrap)

Two years I used the Reddit API to pull stories into a Rails app I built. I wanted to come back to it to refresh myself on RoR. It seems like I got all of the updates working and can sometimes run it, but here are my issues:
1) Reddit now requires Oauth2 for API requests. I'm using the Redd gem and am able to get authenticated, but I get the 429 error (too many requests) error.
I copied from the Redd instructions the following into my model (substituting my info from my registered Reddit app page):
# Authorization (Web)
w = Redd.it(:web, "_myClientId_", "_My_Secret", "_myRedirectURI", user_agent: 'ruby:edswartz.com.myredditapp:v1.0 (by /u/edswartz')
url = w.auth_url("random_state", ["identity", "read"], :permanent)
puts "Please go to #{url} and enter the code below:"
code = gets.chomp
w.authorize!(code)
# Authorization
re = Redd.it(:script, "_my_Client_ID_", "_my_secret_", "_my_user_name_", "_my_password_", user_agent: 'ruby:edswartz.com.myredditapp:v1.0 (by /u/edswartz')
re.authorize!
edAgent = 'User-Agent: ruby:com.edswartz.trueQuotes:v1.0 (by /u/edswartz)'
response = JSON.load(RestClient.get('http://reddit.com/.json'),{'User-Agent'=> edAgent})
After successfully authenticating (copying and pasting the code into the console) I usually get a 429 error. What am I doing wrong? I'm not trying to spoof the user agent, but have put it in manually. I just don't know how else to do it.
The times that I do get in and see the site appear it is obvious that Bootstrap has not loaded. In looking at the Rails-Bootstrap documentation I see where the Gem name has changed and the application css. My /app/assets/stylesheets/application css looks like this:
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
#import "bootstrap";
*/
Again, not sure this is right either but have tried to comply with the read me from https://github.com/twbs/bootstrap-rubygem
Any help anyone can provide on either of these issues would be much appreciated.
I resolved the Bootstrap question. I was using Bootstrap 4. When I went back to Bootstrap 3, and moved the #import directives in the SASS file out of the comments section AND changed the "span4" class to "col-md-4" everything worked.
The user agent seems to be working more often so it might have been a caching issue?
In any event, onward.

AWS to serve CSS images Sinatra

I am using the asset_sync gem to sync my assets to a S3 bucket. In production i want to use S3 and in development i want to use my local files. So i have setup the following along with a helper
environments/development.rb
configure :development do
set :asset_host, "/"
end
environments/production.rb
configure :production do
set :asset_host, "https://s3-eu-west-1.amazonaws.com/#{ENV['FOG_DIRECTORY']}"
end
helper
helpers do
def aws_asset( path )
File.join settings.asset_host, path
end
end
So in my views i can do this
<%= image_tag( aws_asset "/assets/images/wd.png") %>
Which will result in rendering that image from my local assets if in development or from my bucket when in production
So what if i want to render an image from within my main.css file, such as a background image? I cant do the below for example as its not an erb file
main.css
header{
background: #ffffff url('<%= aws_asset("/assets/images/bgwRpeat.png") %>') repeat-x;
}
So what can I do? Has anyone done this before
Thanks for any help anyone can offer
3 ways come to mind.
Precompile the assets
Before you deploy, precompile the assets and CSS. If you create a file called main.css.erb and then run it through ERB to produce main.css it'll have the right stuff inside. This would be my preference. There are lots of ways to precompile, I prefer Guard but YMMV.
Edit:
Lifted and twisted from the Guard::Erb docs
guard 'erb', :input => 'app/views/stylesheets/main.css.erb', :output => "public/assets/stylesheets/main.css" do
watch (%r{app/views/stylesheets/main.css.erb})
end
Something like that.
Create a route that then compiles the assets
This is similar to how you might use SASS templates with Sinatra (if you don't precompile them). Just do the same as above, set up a route for main.css, run the main.css.erb template through ERB and serve it. Add lots of caching.
Edit:
get "/assets/stylesheets/main.css" do
# remember to look at caching
erb :"stylesheets/main.css"
end
I started writing and I can't remember the 3rd :) In my defence, I've a terrible headache. Perhaps someone else will remember for me.

How to set HTTP response (cache) headers in a Sinatra app hosted on Heroku

I have a fairly simple app (just one index.html file and a css file - it really is just a static page) hosted on Heroku.
I use Sinatra to host it on Heroku. The 'app' itself is fairly simple:
require 'rubygems'
require 'sinatra'
get "/" do
File.read(File.join('public', 'index.html'))
end
The question is, how do I set the HTTP response header for the static assets? In particular, I wanted to set the Expires header for caching purposes.
EDIT: I'm looking to add the said header to the static assets (ie, the one that resides under /public, like background images, icons, etc)
Apart from the fact that I wouldn't get through the Sinatra stack just to serve static files, you'd call
cache_control :public, max_age: 60
to cache for a minute. cache_control is a helper that comes with Sinatra.
Otherwise, I'd suggest you have a look at http://www.sinatrarb.com/configuration.html to see how Sinatra is set up so you don't have do deal with serving static files.
Hope this helps.
edit: I just saw you were explicitly asking for the Expires header. I'm not sure, but that should be fairly the same way as Cache-Control. Sorry for the confusion
As an expansion to #awendt's answer, Sinatra can actually handle static files with out needing to explicitly define the route and print the file.
By adding:
set :static, true
..you can add your index.html and stylesheet.css to a public/ folder. Then when you visit http://localhost:9292/stylesheet.css you'll be provided with the static file.
If you want to use another folder name, instead of the default public/, then try:
set :public, "your_folder_name"
If we want to be less explicit we can just create the public/ folder in the knowledge that Sinatra will enable :static for us anyway :)
Source: http://www.sinatrarb.com/configuration.html#__enabledisable_static_file_routes

Generate URL for file in /public in Rails 2 ERB view

In my rails (v2.3.8) app I have a static resource file which I've put at /public/myfile.kml No need for any special routes.rb setting right?
It serves up just fine at http://localhost:3000/myfile.kml
When I deploy (to passenger) it appears at http://myserver/myappname/myfile.kml
All is well so far...
I have a view (an erb file) which spews out javascript which needs to reference this file. The output needs to be '/myfile.kml' on localhost, and '/myappname/myfile.kml' in production, or maybe the full URLs as above, or maybe a relative url involving a bit of '../../../' (awkward with RESTful URLs).
Should I be able to do something like <%=url_for 'myfile.kml'%> ?
or '<%=ROOT_URL%>/myfile.kml'
I know there's an insanely easy answer to this question, but honestly I've had no luck finding it. Quite a few people talking about 'root_url' but what is that? A variable I can reference in a view? It's undefined.
I'm not sure about Rails 2.3.8, but in Rails 3 this value defaults to false.
edit config/environments/production.rb and set:
config.serve_static_assets = true
Also, here's a blog post that shows a helper for linking to a static resource (favicon)
http://ilconnettivo.wordpress.com/2008/07/28/favicon-on-rails/
'<%= ENV["RAILS_RELATIVE_URL_ROOT"] %>/myfile.kml'
<%= RAILS_ROOT + "/public/myfile.kml" %>
Inspection of rake routes reveals the helper root_path for use in views. For example <%= root_path + 'myfile.kml' %> By default will map to files under public/ in a rails application.
The latest (>2.3.6) is Rails.root, see:
http://joneslee85.wordpress.com/2010/05/27/the-dilemma-of-rails-root-vs-rails_root-complex/
Why not just replicate your production environment locally? A webserver is not very resource hungry and it can help resolve some ecosystem configuration issues like you're seeing here.

Ruby / Sinatra - serving up css, javascript, or image files

What is the correct way to route your request through Sinatra so that it serves up the file with no processing? I'm looking for the most common way people do this in the Sinatra framework? I normally place all of my static content in a "content" path.
examples:
/content/css
/content/img
/content/js
How can I use a wildcard to serve up everything under content?
I was surprised there were no real examples of this here:
http://sinatra-book.gittr.com/
Sinatra and Rails use the path public for static content - e.g., ./public/javascripts/. All files in these paths would then be served by the web server (e.g. Thin, Passenger), but without the need for /public in the URL (e.g. the file at #{my_app_root}/public/javascripts/application.js would be available via the Web at the URL http://#{my_domain}/javascripts/application.js).
get '/notes/images/:file' do
send_file('/root/dev/notes/images/'+params[:file], :disposition => 'inline')
end

Resources