Pre-compiling issues using the Cloudinary gem - ruby-on-rails

I'm using Cloudinary in my application and it works like a dream in my dev environment. However, when I deploy the app to Heroku and visit a page that has cl_image_tag, it gives me the "something went wrong" page.
When I look at the log it gives me this error:
ActionView::Template::Error ( isn't precompiled)
This is the line causing the problems:
<%= cl_image_tag(t.image, width: 175, height: 175, crop: :fill, gravity: :faces, border: { color: '#CCC' }) unless t.image.nil? %>
Any help is greatly appreciated.

This error is thrown when the image is nil. Maybe the image attribute of t is nil in this case?

Related

Rails 4 + Sass - No background image in production

I know there are alot of similar questions/answers on SO about this, and I have tried at least 7 of the proposed methods. I can display my app's background image locally in a variety of ways. After trying for nearly 40 hours, there seems to be no way to render it in production. It runs on the following:
Ruby 2.1.5
Rails 4.1.8
Puma 2.1 via Amazon Elastic Beanstalk (single instance - no load balancer)
I've tried every combination of config.serve_static_assets=[true|false] and setting RAILS_SKIP_ASSET_COMPILATION to true and false.
Ran rake assets:precompile RAILS_ENV=production
Tried every path I can think of, but it's not finding the background image. One thing I noticed was that precompilation changes the name of the image when it copies to the public/assets directory. (example: "foo.jpg" becomes "foo-ilfajwe8hjsa8erfjsdf.jpg") So I tried copying the original image files to the new public/assets directory, hoping the app would find them there. That didn't work.
I'm thinking it might be how I'm referencing it in my css, because oddly the favicon file displays as does the fonts from my app's "fonts" folder. And both have their names appended to just like the background image.
Here is my application.html.erb..
<!DOCTYPE html>
<html>
<head>
<title>Capstone v1.4.5</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<%= favicon_link_tag 'capstone_icon.png' %>
</head>
<body>
<% if notice %>
<p class="alert alert-success"><%= notice %></p>
<% end %>
<% if alert %>
<p class="alert alert-danger"><%= alert %></p>
<% end %>
<%= render 'navigation' %>
<main>
<%= yield %>
</main>
</body>
</html>
Here is the application.css.sass..
/*
*= require bootstrap.min
*/
#import "bootstrap-sprockets"
#import "bootstrap"
#font-face
font-family: 'Cinzel-Regular'
src: font-url('Cinzel-Regular.ttf')
#font-face
font-family: 'Oxygen'
src: font-url('Oxygen.otf')
html
position: relative
min-height: 100%
body
background-image: image-url("snowy_prairie_bg.jpg")
background-repeat: no-repeat
background-position: center top
font-family: 'Oxygen'
margin: 0 0 95px
The contents of my public directory (after precompilation)
application-6cca23f2f72df0ad7d26279535719396.css
application-6cca23f2f72df0ad7d26279535719396.css.gz
application-fddd9c84ba451526dbd2ef5bf46e494c.js
application-fddd9c84ba451526dbd2ef5bf46e494c.js.gz
bootstrap
capstone_icon-ed6ffe0ae4bbbb56a8b74a4d7ff230cf.png
capstone_icon.png
Cinzel-Regular-59dcda430d3afc3ace221f1835d7fb08.ttf
images
manifest-73d04c0fd1290b15fb280becfcf62b7b.json
Oxygen-1c736bd9242de63cf87c07f0a48c9b5c.otf
Oxygen-Bold-01bc72645c864aa090d57754565ef634.otf
Oxygen-BoldItalic-cfe32a5aedef7b25f8b1efdfcbdbd72a.otf
Oxygen-Italic-2a51c29c8f2bd242ac27e6fb7860f6a1.otf
snowy_prairie_bg-d246fbbe1178a09d38df31be96aee79a.jpg
snowy_prairie_bg.jpg
Am I referencing the image wrong in my css? Again, it renders great locally. Should I be using Passenger instead of Puma? This is not a very small app and I've got alot invested in the database, also hosted on Amazon. But like I said, I'm approaching 40 hours just trying to get this background rendered.
If you have any ideas, please help. I am willing to try anything!
Thank you
FYI - the above bootstraps, fonts, other images and sass styles render perfectly. It's just the background image. Thanks
EDIT: When I go to the page, capstonesavings.com, the following error is shown in the dev. console: Failed to load resource: the server responded with a status of 403 (Forbidden). Do I need to change permissions on something?
OK, SO I THINK I FIXED IT!
Most of the above code is correct, but I changed the following from the above application.css.sass..
Changed
background-image: image-url("snowy_prairie_bg.jpg")
To
background-image: asset-url("snowy_prairie_bg.jpg")
Then, I SSH'ed into the instance (eb ssh) and did the following:
cd /var/app/current
followed by
sudo chmod 755 public/assets/snowy_prairie_bg-d246fbbe1178a09d38df31be96aee79a.jpg
I had tried the above change to the SaSS before, but it didn't work without changing permissions. Thanks to Chrome developer tools, I noticed a (tiny) error flag when the page was rendered. I clicked it and it showed the 403 error that I added in the above edit. This is some stuff that Amazon uses to make things secure, since I guess you can route your log files, etc. to the associated S3 bucket. So that's why I explicitly targeted the image in question when changing the perms. This site isn't going to have a ton of images, but if it did I'd probably take the time to elaborate on the storage within the bucket and set broader perms accordingly.
This saved the day for me. Hope it helps someone else.

only display an image if it's present in rails app

I have a blog page on my website and some posts have images and some don't. If there wasn't an image it was showing an error so I changed the code to only show if an image is present
.post_body
= #post.body.html_safe
- if #post.image
= filepicker_image_tag #post.image, w: 208, h: 208, fit: 'clip'
On my localhost, this worked well to solve the problem and nothing was displayed if I hadn't added an image to the post. But when I push it to heroku, my code changes haven't made any difference. If there is no image on the post it shows a broken image icon.
Does anyone know why this would be fine in localhost but not online?
Thanks
Add condition, like this
filepicker_image_tag #post.image, w: 208, h: 208, fit: 'clip' unless #post.image.blank?
or
.post_body
= #post.body.html_safe
- if #post.image.present?
= filepicker_image_tag #post.image, w: 208, h: 208, fit: 'clip'

default image from localhost rather than loading from cloudinary

I am using cloudinary to store user avatars in my rails 4 application. I also have a placeholder image in my image assets. I wanted to know that if a user hasnt uploaded his avatar, how do i load it from the localhost.
As of now i have to add checks as
- if user.avatar.present?
= cl_image_tag(user.avatar.filename, width: 46, height: 46)
- else
= image_tag 'default.png', style: 'width:46px; height:46px;'
i can specify a default image as
= cl_image_tag(user.avatar.filename, width: 46, height: 46, default: 'default.png')
but the default image has to be stored on cloudinary. I dont want to store it on cloudinary since cloudinary charges for data transfer. hence, i have stored 'default.png' is stored in assets. 'cl_image_tag' is a helper provided by cloudinary to load images from there.
I solved the problem as below
Firstly, the default images need to be saved on cloudinary.
eg
<%= cl_image_tag("non_existing_id.png", width: 100, height: 100, default_image: "avatar.png") %>
if you dont want to load default image from cloudinary but from our localhost, add the below code in a partial and use this partial.
- if user.avatar.present?
= cl_image_tag(user.avatar.filename, width: 46, height: 46)
- else
= image_tag 'noPic_80.png', style: 'width:46px; height:46px;'

can caching information attached to image file names cause a 404 error?

I deployed a Rails app successfully, however, the images are not displaying. This is the 404 error that's showing in the console
GET http://mydomain.com/assets/myimage.png 404 (Not Found)
Inside my application directory on my server, there's three subdirectories
current releases shared
which is a setup created by the deployment script I borrowed from Ryan Bates.
I can see the images in the images directory of the assets folder in current
current/app/assets/images$ ls
glyphicons-halflings.png glyphicons-halflings-white.png qb.png
However, in the assets folder of the shared directory (which is I'm guessing where they're being put after everything's compiled for production), the same images have some (I'm assuming) cache information attached to them, such that the image I want isn't
myimage.png
but rather
myimage-0bb3f134943971c95b2abdfd30f932c7.png
I'm wondering if this is what's causing the 404 error, as (I'm assuming) the code's looking for myimage.png in the shared/assets directory.
Do you know how I can deal with this problem?
contents of /shared/assets
/shared/assets$ ls
application-39c95ed7b8d86b0698b6c443563e33c7.js fontawesome-webfont-c4adb9424c8b6a6b1b9b0d2627528c4c.woff
application-39c95ed7b8d86b0698b6c443563e33c7.js.gz fontawesome-webfont-f57557847fd1897100790d9df344ded8.ttf
application-7a6376d676fb88537b9f839687ccaad3.css glyphicons-halflings-4e5b89324f1ac987ddf6835ef51f5fe9.png
application-7a6376d676fb88537b9f839687ccaad3.css.gz glyphicons-halflings-white-2fa53df59ca25ee50f59f971c0c9175d.png
application-a184171300937caf263adbc5e8582ba4.css manifest-990c8a24196fee5e9c394078c326c763.json
application-a184171300937caf263adbc5e8582ba4.css.gz myimage-0bb3f134943971c95b2abdfd30f932c7.png
fontawesome-webfont-57b442a30fcae0d4334299c521a326a2.svg twitter
fontawesome-webfont-8140ac47a16c8f7074e59f2ebe0657eb.eot
code used to display images
For one image, I create a span like this
and then assign it a background image
.qb{
position: absolute;
width: 50px;
height: 50px;
background-image: url('/assets/qb.png');
left: 75px;
top: 300px;
}
For another image, I have a template like this with a class that automatically uses Twitter bootstrap to create a x to let uses click and remove a page element
<script id="blahblah_template" type="text/underscore">
<h2> The Story <i class='icon-remove'></i></h2>
It's triggering a 404 even though the image is on the server
Failed to load resource: the server responded with a status of 404 (Not Found)
http://mydomain.com/assets/glyphicons-halflings.png
you should use asset helpers provided by rails which would automagically create the right url to the image with caching build in. here is how:
.qb{
position: absolute;
width: 50px;
height: 50px;
background-image: url( <%= asset_path 'qb.png' %> );
left: 75px;
top: 300px;
}
the above will map qb.png to qb-0bb3f134943971c95b2abdfd30f932c7.png & also update the url once the caching fingerprint changes. just make sure that your stylesheet filename has .erb at the end, something like stylesheet.css.erb
see The Asset Pipeline guide for more information
[edit]
For Bootstrap integration with rails asset pipeline, kindly use gem like bootstrap-sass. it will fix your issues with images

JW-Player and Rails 3.2

I'm trying to use JW-Player in my application. Researching the issue a bit, there seems to be several abandoned efforts to produce a gem, and the latest is undocumented. So, here's how I'm going about it:
I downloaded the JW-Player version 6, unzipped and copied the files in my /app/assets/javascripts directory as follows:
app/assets/javascripts/jwplayer/jwplayer.js
app/assets/javascripts/jwplayer.html5.js
app/assets/javascripts/jwplayer.flash.swf
In my app/views/layouts/application.html.erb, I have the following:
<head>
<%= javascript_include_tag "/assets/javascripts/jwplayer/" %>
</head>
and in app/views/pages/about.html.erb, I have the following:
<%= jw_player("http://xxxxx/video.mp4",
:width => 200, :height => 110) %>
Here's what happens when I click on the About page link:
Showing xxxxxxxx/app/views/pages/about.html.erb where line #10 raised:
undefined method `jw_player' for #<#<Class:0x007fe77e37c018>:0x007fe780c1f678>
First time user of JW-Player.
When implementing JWPlayer 6.6, we stood before the choice of putting the jwplayer.flash.swf file into the public folder, to make the flash mode work, but it seemed very messy to have the files separated like that. What I did in the end to make it work both on development and production was:
Put all 3 files to vendor/assets/javascripts/jwplayer
Rename jwplayer.js to jwplayer.js.erb
Inside jwplayer.js.erb, update the flash file path config like this (the 1st line with the html5 file path config is just for reference)
j={type:"html5",src:e.base+"jwplayer.html5.js"},
b={type:"flash",src:"<%= asset_path('jwplayer/jwplayer.flash.swf') %>"};
(note that the "e.base+" before the path was removed for the flash file path - that's the trick that allowed working relative paths in the development environemtn)
In my understanding, the JWPlayer license allows modifications like this:
"Adaptations
Publisher shall be permitted to make Adaptations reasonably necessary for the purpose of exercising its rights under these Terms of Service, such as Adaptations to integrate the Products into Publisher’s websites or other properties. All Adaptations created by Publisher are strictly for its own Use and Publisher is prohibited from Distributing any Adaptation it creates. The Company reserves the right to prohibit the Use of any Adaptation in its sole discretion."
I have just finished working on a gem started by choix and improved by mattherick called jwplayer-rails that probably worked in older version of rails. It wasn't working with the assets pipeline but mattherick did a great job at fixing that up and I went on to update JWPlayer to the newest version.
You can see the repository here.
The following instructions are right out of the repo above.
To add this gem to your rails app just add this line to your application's Gemfile:
gem 'jwplayer-rails', :git => 'git://github.com/dutgriff/jwplayer-rails.git'
To use it first include assets on the page
<%= jwplayer_assets %>
Then place a div with JW Player
<%= jwplayer %>
You can pass options to jwplayer helper to customize it:
<%= jwplayer({width: 500, height: 200}) %>
More information for customization could be found here.
It works great for me so far but if you find an issue let me know on here or github.
I've found a solution to this.
The main issue you need to work-around is that jwplayer.js wants to fetch jwplayer.flash.swf and jwplayer.html5.js based on the path of jwplayer.js.
You can see that in Chrome Developer Toolbar for jwplayer.js (with pretty print):
(h.embed.config = function(b) {
var e = {fallback: !0,height: 270,primary: "html5",width: 480,base: b.base ? b.base : j.getScriptPath("jwplayer.js"),aspectratio: ""};
b = j.extend(e, h.defaults, b);
var e = {type: "html5",src: b.base + "jwplayer.html5.js"},
g = {type: "flash",src: b.base + "jwplayer.flash.swf"};
You can use that base property as an undocumented api to tell jwplayer where the jwplayer.flash.swf and jwplayer.html5.js can be found.
Example:
jwplayer("player-id").setup({
width: 640,
height: 480,
file: "www.w3schools.com/html/movie.mp4",
base: "http://cloudfront.net/assets/vendor/jwplayer/"
};
Then it will look for http://cloudfront.net/assets/vendor/jwplayer/jwplayer.flash.swf. Note: jwplayer has no notion of the asset pipeline fingerprint filenames, so make sure you sync both the file with md5 and without.
This worked for me:
Place jwplayer folder in public (Downloaded from longtail video)
Include it like an external script, without using asset pipeline (HAML).
%script{:src => '/jwplayer/jwplayer.js'}
In your video partial (ERB)
<script type="text/javascript">
jwplayer.key="Your key here";
$(document).ready(function(){
jwplayer("video").setup({
height: 360,
width: 640,
playlist: [
<% videos.each do |v| %>
{
image: "<%= v.poster %>",
sources: [
{ file: "<%= v.url %>" },
]
},
<% end %>
]
});
})
</script>
<video id="video">Video Loading... Ensure JavaScript is enabled...</video>
Did you restart the server after downloading the player and including it in your layouts. This could be one reason of failure.
Download jwplayer from http://www.longtailvideo.com/jw-player/download/
Put these files to the particular directory:-
app/assets/jwplayer/jwplayer.flash.swf
vendor/assets/javascripts/jwplayer.js
vendor/assets/javascripts/jwplayer.html5.js
Then add these line in application.js
//= require jwplayer
//= require jwplayer.html5
On the page where you are playing video, add these lines
<script type="text/javascript">jwplayer.key="YOUR_JWPLAYER_KEY";</script>
<div id="video">Loading the player ...</div>
<script type="text/javascript">
jwplayer("video").setup({
flashplayer: "<%=asset_path('jwplayer.flash.swf')%>",
file: "<%= file_path %>",
height: 360,
width: 640,
analytics: {
enabled: false,
cookies: false
}
});
http://account.longtailvideo.com/#/home from where you can get your free self hosted key in signing up from Get Your License Key portion.
I also chose JWplayer.
Here are my steps.
I'm using https://github.com/choix/jwplayer-rails gem.
Added
gem 'jwplayer-rails', '1.0.1'
to my Gemfile.
Did all things from above page; in a show.html.slim view file included these lines:
= jwplayer_assets
br
br
= jwplayer({file:#lesson.media_file})
lesson.media_file attribute contains file location. For a video file project/public/videos/videoclip.webm, media_file contains string "/videos/videoclip.webm".
Hope this will be useful.

Resources