No route error for images refereed to by javascript stylesheets - ruby

I just migrated my rails 2.3 application to rails 3.2 (a bit late but I did it)
Everything else seem to work fine except I get no route error for images which are referred to by javascript stylesheets.
The rake assets:precompile task creates all the image names with appended hash also for images which are required by js stylesheets for example jquery dialog etc.
How can I fix this?

Related

livereload only responding to css changes, not html

I have installed livereload gem, which I'm using with a ruby middleman application. However, it's only autoloading changes to the css. If I make changes to the html files, I still have to restart the server to view the changes. Is there somehow I can make it autoload html changes?
It seems that this feature doesn't work on all versions of livereload and also depends on the browser and it's extensions. Try to also change a css file when you change the html so that the refresh occurs. Also, have you looked at https://github.com/guard/guard-livereload ? That has an example watching the change of html.
guard 'livereload' do
watch(%r{app/views/.+\.(erb|haml|slim)})
watch(%r{app/helpers/.+\.rb})
watch(%r{public/.+\.(css|js|html)})
watch(%r{config/locales/.+\.yml})
# Rails Assets Pipeline
watch(%r{(app|vendor)(/assets/\w+/(.+\.(css|js|html))).*}) { |m| "/assets/#{m[3]}" }
end

Rails 3.1 assets pipeline, how does it handle files with the same name? priority?

This is problem, I'm using Typus, which includes a fancybox jquery plugin under /vendor/assets. That fancybox version is too old (1.3.4) and it does not work with rails 1.9.x so I need to replace that with fancybox 2.x that works with that version of jquery because the rest of my site uses jquery 1.9.
Typus's application.js manifest loads fancybox this way
//= require jquery.fancybox-1.3.4.pack
so I thought I could just add fancybox 2 with that file name and the asset pipeline would use that version instead but it's not, it's loading the file inside /vendor/assets.
So, my question is, how does rails handle that case when there's more than one file with the same name? is there any priority? and most important, can I change that so the files under /app/assets have more priority?
I've read it uses the first file it finds with the name but I don't know how to tell rails to look in some folder first.
I've tried
config.assets.paths = [Rails.root.join('app','assets')]
or
config.assets.paths = [Rails.root.join('app','assets'),Rails.root.join('vendor','assets')]
on my config/application.rb but it keeps using the file under /vendor/assets
I don't want to fork>modify Typus, I want to tell rails to use my jquery.fancybox-1.3.4.pack.js version of the file
I've seen on github that the last commit on Typus downgrades jquery to 1.8.x but I can't do that, I need jquery 1.9.
I'm also trying to override Typus's application.js inside my project but with no luck.

Not finding coffeescript views in Rails production environment

I'm working with a rails 3.1 app. I have a comments controller that uses ajax to update the page. There is a create.js.coffee in views/comments that should get rendered when a comment gets created. This works just fine in the dev env, but when i run the app in production rails can't find the view. It is like the asset pipeline isn't including it in production mode.
Code can be found here: https://github.com/samnang/ajax_rails31_demo
The problem is that you need to have the coffee-rails gem available to the production environment. https://github.com/samnang/ajax_rails31_demo/issues/1#issuecomment-2297130
Serving JS up in requests is not supported by rails out of the box so I took another tack.
This author suggests http://www.alfajango.com/blog/rails-3-remote-links-and-forms/ taking full advantage of UJS. This seems to be the trending pattern for updating the page after an xhr. So now my controller always renders html and I use the ajax:complete callback to append the xhr.result_text. Tip: If you haven't seen jQuery's live() method, check it out. It is of great use with this pattern.
You have to precompile the assets as part of your deployment:
rake assets:precompile
or turn on the pipeline (which has a minor performance hit):
# config/environment/production.rb:
config.serve_static_assets = true

Rails 3.1/Sprockets: Injecting controller variables (or helpers) into javascript assets

I have an action with
def new
#test_var = 'i want this to show'
end
All I want to do is inject that into the javascript called for that page. For example:
#app/assets/javascript/my_model.js.coffee.erb
$ ->
console.log('<%= #test_var %>')
I'm guessing this doesn't work because that the coffeescript/erb is compiled before the controller is accessed...so, if I wanted to inject controller variables into a JavaScript file (client side - NOT accessed via ajax) in 3.1, how should I go about doing it?
I believe the problem is that you're thinking about the asset pipeline all wrong...
asset being the operative word.
It's not a view pipeline. Other things which are assets? images & css files, things which can be preprocessed and then served as-is. The erb/preprocessing of your assets doesn't occur on each pageload/request, rather it occurs on startup/filechange so in production said assets can be optimised, cached and served statically.
You could probably figure out a way to achieve it using Live Compilation (see section 4.2 of http://guides.rubyonrails.org/asset_pipeline.html) but as the docs say:
This mode uses more memory and is lower performance than the default. It is not recommended.
The bad answer would be 'inject the javascript into your view', but decoupling your javascript from your rails controllers/views is a good idea.
A better answer would be to have an asset folder containing all of your controller javascripts, and use some "what page am I on?" javascript to determine whether to run the code or not.
Here's some answers that explain various approaches to this:
Rails 3.1 asset pipeline: how to load controller-specific scripts?
Using Rails 3.1, where do you put your "page specific" javascript code?

Static web site generation

I need an easy way to generate static web pages so that I can serve them up with Apache or Nginx. Currently I am using SproutCore's build tool (Abbot) to generate static pages but that is a little bit cumbersome as it is designed for building SproutCore apps, not non-SproutCore HTML pages.
Here are my requirements:
Javascript must be combined and minified
CSS files must be combined
Each image / CSS / Javascript asset must have unique URL for better caching (query string isn't enough)
Asset URL should be different only when it really changes
Localization support thorough HTML, CSS, Javascript and image files
Nice template engine with layouts, partials etc.
Here are possible solutions I have found:
Create the site using Ruby on Rails, then get all resources using wget like http://usefulfor.com/ruby/2009/03/23/use-rails-to-create-a-static-site-rake-and-subversion/
Use Middleman: http://middlemanapp.com
Any thoughts on this?
After a longish evaluation process I have decided to use Middleman. It does the trick and I love its simplicity and the fact that I can use existing Rack components with it.
Best Regards,
Pekka Mattila
I'm the creator of Middleman and would be eager to help you get comfortable using Middleman. My main goal is to give users the power of Rails, but focused on static development. Some of the actual code of Middleman is simplified versions of Ab
Here's what I do:
Ruby on Rails 3 with the High Voltage Gem, which makes it easy
to serve a static page body using the common templates. It requires a
simple entry in the routes (and you can use namespaces to create a
hierarchy).
Apache reverse proxy to stand-alone Passenger (which uses nginx I
believe) to run the Rails app. This article describes how to
configure it.
Stand-alone passenger will read the URL, see if there is a corresponding file in /public with the .html on it, and serve that. If not found, it will invoke Rails and generate the page. In essence, page caching, with the option of publishing your URLs with or without the .html. There is a section in the Passenger docs about page caching specifically.
As far as combining and minifying js and css, here's a good stackoverflow thread.
Rails has excellent i18n/l10n support.
Rails template engine is very nice to work with. And you can use HAML if you prefer.
For your 3rd and 4th points, I'm a little confused. You want css and js combined, but then you want each to have it's own URL. In Rails, the "cache => true" directive on asset tags takes care of adding a query string parameter that changes when the content does, which is a fairly traditional scheme. I'm not sure what context you are working in where that would not work. Any CDN I've ever used works fine with that, as does an web server implementing the HTTP spec correctly. Anyway, changing the actual path or file in the URL would require changing all references to it. Maybe I'm misunderstanding?
Monkeyman has the template engine you need, I think. Think of it as Middleman's little Scala brother. Nowhere as mature or feature rich yet, but we'll get there eventually. The current incarnation supports HAML, Jade, SSP for layouts, Markdown for content and a couple of other things.
Without any special order
jekyll - quite simple
middleman - a lot of funcionalities
nanoc - a lot of funcionalities
stasis - use controllers
staticmatic
frank
gumdrop
ruby on rails + wget
ruby on rails + high voltage + apache reverse proxy
You should probably also checkout mod_pagespeed. It will at least give you this:
Javascript must be combined and minified
CSS files must be combined
Each image / CSS / Javascript asset must have unique URL for better caching (query string isn't enough)
Asset URL should be different only when it really changes
It won't give you this:
Localization support thorough HTML, CSS, Javascript and image files
Nice template engine with layouts, partials etc.
You can have a look at docpad. It's written in coffeescript and runs on Nodejs. It is document based, where you write some documents and layouts, it will compile them and write them in the out directory. You can write documents in a lot of languages via plugins
It also supports multiple level of file compilation. For example from eco to markdown to html.
Another great feature of it is that you can query on other documents being generated in a document. For example in the first page, you have something like this to get all blog posts:
database.findAll({url : /posts/})
Which will return all documents having posts in their url.

Resources