Rectangle 27 3

You are not using the asset pipeline - you are not using the fingerprinted, cached version of the files. To use the asset pipeline, you need to use the new helpers that point to the fingerprinted, cached version of the files. To do this, either embed erb in your css, or use sass. I'll use sass in my example:

Incorrect (doesn't use the asset pipeline):

.class
  background-image: url('image.jpg')

Correct (uses the asset pipeline):

.class
  background-image: image-url('image.jpg')

javascript - Background images in rails production don't work - Stack ...

javascript ruby-on-rails image asset-pipeline production-environment
Rectangle 27 37

You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as <%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag params[:controller] %>.

Now, you could do as they suggest and load specific stylesheets for each controller, but it does not work as they suggest out of the box. The neglect to mention a few things you must do.

You need to remove the //= require_tree . directive from application.css, which, left in place, will load every other asset in the folder. This means that every page would load users.css, and if you added the controller-specific stylesheet line as in their example, it would load the controller stylesheet twice.

You would need to tell Rails to precompile the individual files. By default, all *.css files besides application.css are ignored by the precompiler. To fix this you'd have to do edit your config to do something like this:

# in environments/production.rb
# either render all individual css files:
config.assets.precompile << "*.css"
# or include them individually
config.assets.precompile += %w( users.css static_pages.css )
  • Finally, as instructed by the Rails guide, you'd need to change your stylesheet includes to look something like: <%# this would now only load application.css, not the whole tree %> <%= stylesheet_link_tag :application, :media => "all" %> <%# and this would load the controller specific file %> <%= stylesheet_link_tag params[:controller] %>

However, the above may not be truly the best practice. Sure, sometimes you might want individual stylesheets, but most the time you probably just want to serve your style bundle so the client can cache one file. This is how the asset pipeline works out of the box, after all.

Besides that, if you were to just add override rules in your controller specific stylesheets, then you're creating a load-order-specific tangle of styles right out of the gate. This... is probably not good.

A better approach might be to namespace the styles in the controller sheets, something like this:

// in application.css (or some other commonly loaded file)
background-color: $color1;

// in users.css.scss
body.controller-users {
  background-color: $color2;
}

// and so on...

Then in your layout, add the controller name to the body class, like:

<body class="controller-<%= params[:controller] %>">

In this way, your styles are resolved by namespace, not just load order. Furthermore with this solution you could still go ahead and load separate controller-specific stylesheets if you desire, or you could forget about that and just let everything be compiled into application.css as it would be by default. All the styles would be loaded for each page, but only the controller-specific styles would apply.

This is a great answer, all the more because it takes a good practice, commonly shared in this community, it shows its downsides and it proposes a much better alternative. Many thanks!!

css - Controller specific stylesheets in rails 3: Inheritence - Stack ...

css ruby-on-rails sass
Rectangle 27 223

I've discovered a way to make it less rigid and future proof by still using the asset pipeline but having the stylesheets grouped. It's not much simpler than your solution, but this solution allows you to automatically add new stylesheets without having to re-edit the whole structure again.

app/assets/stylesheets
app/assets/stylesheets
+-- all
    +-- your_base_stylesheet.css
+-- print
    +-- blueprint
        +-- print.css
    +-- your_print_stylesheet.css
+-- ie
    +-- blueprint
        + ie.css
    +-- your_ie_hacks.css
+-- application-all.css
+-- application-print.css
+-- application-ie.css

Then you edit the three manifest files:

/**
 * application-all.css
 *
 *= require_self
 *= require_tree ./all
 */

/**
 * application-print.css
 *
 *= require_self
 *= require_tree ./print
 */

/**
 * application-ie.css
 *
 *= require_self
 *= require_tree ./ie
 */
<%= stylesheet_link_tag "application-all", :media => "all" %>
<%= stylesheet_link_tag "application-print", :media => "print" %>

<!--[if lte IE 8]>
    <%= stylesheet_link_tag "application-ie", :media => "all" %>
<![endif]-->

Lastly, don't forget to include these new manifest files in your config/environments/production.rb:

config.assets.precompile += %w( application-all.css application-print.css application-ie.css )

As Max pointed out, if you follow this structure you have to be mindful of image references. You have a few choices:

Move the images to follow the same pattern

  • Note that this only works if the images are not all shared
background: url('/assets/image.png');
background: image-url('image.png');

While this is a nice organization of the files, I believe it still solves the essential problem in the same way the question itself does.

@semperos, you're correct that the shape of the solution is essentially the same but my proposal still allows us to use the asset pipeline for the entirety of the stylesheets. I'm not sure if there's another way to selectively include part of the styles unless it's on a separate stylesheet. At least this way we compile to only a handful of CSS files.

Something like this in the Rails Asset Pipeline guide would be good actually. thanks

There is a gotcha though: if you follow this structure and use simple .css files then all your images will be broken. E.g. background: url('image.png') will be translated to the path /assets/all/image.png (mind the all in the path). Instead this works: background: url('/assets/image.png). If there is an easier solution to this please post it. Other than using SASS which has helpers methods that probably resolve the path correctly.

@ExiRe, yes. Any stylesheets or JS files/manifests that don't follow the standard pattern need to be added to the precompile array (see: guides.rubyonrails.org/asset_pipeline.html#precompiling-assets)

Using Rails 3.1 assets pipeline to conditionally use certain css - Sta...

css ruby-on-rails-3.1 asset-pipeline sprockets
Rectangle 27 222

I've discovered a way to make it less rigid and future proof by still using the asset pipeline but having the stylesheets grouped. It's not much simpler than your solution, but this solution allows you to automatically add new stylesheets without having to re-edit the whole structure again.

app/assets/stylesheets
app/assets/stylesheets
+-- all
    +-- your_base_stylesheet.css
+-- print
    +-- blueprint
        +-- print.css
    +-- your_print_stylesheet.css
+-- ie
    +-- blueprint
        + ie.css
    +-- your_ie_hacks.css
+-- application-all.css
+-- application-print.css
+-- application-ie.css

Then you edit the three manifest files:

/**
 * application-all.css
 *
 *= require_self
 *= require_tree ./all
 */

/**
 * application-print.css
 *
 *= require_self
 *= require_tree ./print
 */

/**
 * application-ie.css
 *
 *= require_self
 *= require_tree ./ie
 */
<%= stylesheet_link_tag "application-all", :media => "all" %>
<%= stylesheet_link_tag "application-print", :media => "print" %>

<!--[if lte IE 8]>
    <%= stylesheet_link_tag "application-ie", :media => "all" %>
<![endif]-->

Lastly, don't forget to include these new manifest files in your config/environments/production.rb:

config.assets.precompile += %w( application-all.css application-print.css application-ie.css )

As Max pointed out, if you follow this structure you have to be mindful of image references. You have a few choices:

Move the images to follow the same pattern

  • Note that this only works if the images are not all shared
background: url('/assets/image.png');
background: image-url('image.png');

While this is a nice organization of the files, I believe it still solves the essential problem in the same way the question itself does.

@semperos, you're correct that the shape of the solution is essentially the same but my proposal still allows us to use the asset pipeline for the entirety of the stylesheets. I'm not sure if there's another way to selectively include part of the styles unless it's on a separate stylesheet. At least this way we compile to only a handful of CSS files.

Something like this in the Rails Asset Pipeline guide would be good actually. thanks

There is a gotcha though: if you follow this structure and use simple .css files then all your images will be broken. E.g. background: url('image.png') will be translated to the path /assets/all/image.png (mind the all in the path). Instead this works: background: url('/assets/image.png). If there is an easier solution to this please post it. Other than using SASS which has helpers methods that probably resolve the path correctly.

@ExiRe, yes. Any stylesheets or JS files/manifests that don't follow the standard pattern need to be added to the precompile array (see: guides.rubyonrails.org/asset_pipeline.html#precompiling-assets)

Using Rails 3.1 assets pipeline to conditionally use certain css - Sta...

css ruby-on-rails-3.1 asset-pipeline sprockets
Rectangle 27 222

I've discovered a way to make it less rigid and future proof by still using the asset pipeline but having the stylesheets grouped. It's not much simpler than your solution, but this solution allows you to automatically add new stylesheets without having to re-edit the whole structure again.

app/assets/stylesheets
app/assets/stylesheets
+-- all
    +-- your_base_stylesheet.css
+-- print
    +-- blueprint
        +-- print.css
    +-- your_print_stylesheet.css
+-- ie
    +-- blueprint
        + ie.css
    +-- your_ie_hacks.css
+-- application-all.css
+-- application-print.css
+-- application-ie.css

Then you edit the three manifest files:

/**
 * application-all.css
 *
 *= require_self
 *= require_tree ./all
 */

/**
 * application-print.css
 *
 *= require_self
 *= require_tree ./print
 */

/**
 * application-ie.css
 *
 *= require_self
 *= require_tree ./ie
 */
<%= stylesheet_link_tag "application-all", :media => "all" %>
<%= stylesheet_link_tag "application-print", :media => "print" %>

<!--[if lte IE 8]>
    <%= stylesheet_link_tag "application-ie", :media => "all" %>
<![endif]-->

Lastly, don't forget to include these new manifest files in your config/environments/production.rb:

config.assets.precompile += %w( application-all.css application-print.css application-ie.css )

As Max pointed out, if you follow this structure you have to be mindful of image references. You have a few choices:

Move the images to follow the same pattern

  • Note that this only works if the images are not all shared
background: url('/assets/image.png');
background: image-url('image.png');

While this is a nice organization of the files, I believe it still solves the essential problem in the same way the question itself does.

@semperos, you're correct that the shape of the solution is essentially the same but my proposal still allows us to use the asset pipeline for the entirety of the stylesheets. I'm not sure if there's another way to selectively include part of the styles unless it's on a separate stylesheet. At least this way we compile to only a handful of CSS files.

Something like this in the Rails Asset Pipeline guide would be good actually. thanks

There is a gotcha though: if you follow this structure and use simple .css files then all your images will be broken. E.g. background: url('image.png') will be translated to the path /assets/all/image.png (mind the all in the path). Instead this works: background: url('/assets/image.png). If there is an easier solution to this please post it. Other than using SASS which has helpers methods that probably resolve the path correctly.

@ExiRe, yes. Any stylesheets or JS files/manifests that don't follow the standard pattern need to be added to the precompile array (see: guides.rubyonrails.org/asset_pipeline.html#precompiling-assets)

Using Rails 3.1 assets pipeline to conditionally use certain css - Sta...

css ruby-on-rails-3.1 asset-pipeline sprockets
Rectangle 27 10

If I understand correctly, you want to use the asset pipeline's search functionality to locate the local path for a given asset so you don't have to hard-code which directory it's in. If that's the case, you want to do this:

<YourAppName>::Application.assets.find_asset('Rails.png').pathname

This will locate the asset using standard pipeline/sprockets searching, and give you the fully qualified local path to the file.

hi, this gives me the path in 'app/assets/..." but doesn't give the actual asset path in 'public/assets'. it's cool to know this though, but even in production environment it doesn't give me the directory i wanted. good to know though i've added to my notes. thanks

actionmailer - asset_url in mailer on rails 3.1 - Stack Overflow

ruby-on-rails-3 actionmailer asset-pipeline mailer
Rectangle 27 4

Check out the Teabag project on github. It specifically allows you to use the asset pipeline along with Mocha, Jasmine, or QUnit.

Mocha's a pretty great library, but I typically use Jasmine -- for me it's primarily about knowledge and experience with Jasmine, but Mocha has some really cool features -- like letting you know when you're bleeding things into the global scope.

Figured it was worth mentioning the project because it specifically allows you to play around with both (in different suites) so you can decide for yourself.

Jasmine vs. Mocha JavaScript testing for Rails 3.1+ - Stack Overflow

javascript ruby-on-rails jasmine mocha
Rectangle 27 28

Assets like fonts will work on development but not production if you are using regular old css to locate your assets rather than the asset pipeline helpers. Rails 4 added breaking changes to the asset pipeline to encourage people to use it properly, and not use the old css method of referencing assets.

To resolve this, you need to use the new asset pipeline helpers to point to the fingerprinted, cached versions of your fonts. Rather than url (which does not use the asset pipeline), you need to use font-url (which does use it). To do this, you may have to use Sass or embed ERB in your stylesheet.

@font-face {
  font-family: 'Icomoon';
  src: font-url("/assets/icomoon.eot");
  src: font-url("/assets/icomoon.eot?#iefix") format("embedded-opentype"), font-url("/assets/icomoon.svg#icomoon") format("svg"), font-url("/assets/icomoon.woff") format("woff"), font-url("/assets/icomoon.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
}

Thanks, worked for me too. Just make sure that this is put in a .css.scss file though - I got caught out trying to put this in application.css which didn't work, understandably.

I tried this with Rails 4.2 and it works with Heroku. Doesn't even have to add this code: config.assets.precompile += %w( .svg .eot .woff .ttf )

ruby on rails - Heroku font assets not working - Stack Overflow

ruby-on-rails heroku
Rectangle 27 2

If you use the asset pipeline and you want to check whether an asset exists, look for it in the asset folder:

If you have the asset in the public folder, which is not recommended (for various reasons) unless you use Rails < 3 and / or built some asset management extension yourself, you can look for it there:

all_images = 1.upto(100).map do |image_number|
   path = Rails.root.join("public/img/#{image_number}.jpg")
   path if File.exists?(path)
 end.compact

ruby on rails - How to access public folder from a model method? - Sta...

ruby-on-rails ruby
Rectangle 27 2

If you use the asset pipeline and you want to check whether an asset exists, look for it in the asset folder:

If you have the asset in the public folder, which is not recommended (for various reasons) unless you use Rails < 3 and / or built some asset management extension yourself, you can look for it there:

all_images = 1.upto(100).map do |image_number|
   path = Rails.root.join("public/img/#{image_number}.jpg")
   path if File.exists?(path)
 end.compact

ruby on rails - How to access public folder from a model method? - Sta...

ruby-on-rails ruby
Rectangle 27 2

You can also group the js in folders and continue to use the asset pipeline to load your javascript selectively depending on the page.

Using Rails 3.1, where do you put your "page specific" javascript code...

javascript ruby-on-rails ruby-on-rails-3.1 asset-pipeline sprockets
Rectangle 27 9

If you don't want to use the asset pipeline or the complex work arounds to get that necessary page specific javascript (I sympathise), the simplest and most robust way, which achieves the same as the answers above but with less code is just to use:

<%= javascript_include_tag "my_javascipt_file" %>

Note: this does require one more http request per include tag than the answers which use content_for :head

javascript_include_tag was exactly what I was looking for, cheers AJP

where do you put "my_javascipt_file"? In assets/javascripts? But if so, wouldn't that get picked up automatically with a //= require . in the application.js?

@Linus yep, //= require . would bring that script into any page on your site so you'd have to do something like Kenny Grant (use //= require_tree ./global ) or bjg suggested.

This was by far the easiest method for me, I changed //= require_tree . to //= require_directory . in application.js and then created a sub-directory in assets\javascripts. Note that you have to include the new directory in config\initializers\assets.rb to precompile your js by adding the line: Rails.application.config.assets.precompile += %w( new_dir/js_file.js )

Best way to add page specific JavaScript in a Rails 3 app? - Stack Ove...

javascript ruby-on-rails ruby-on-rails-3
Rectangle 27 9

If you don't want to use the asset pipeline or the complex work arounds to get that necessary page specific javascript (I sympathise), the simplest and most robust way, which achieves the same as the answers above but with less code is just to use:

<%= javascript_include_tag "my_javascipt_file" %>

Note: this does require one more http request per include tag than the answers which use content_for :head

javascript_include_tag was exactly what I was looking for, cheers AJP

where do you put "my_javascipt_file"? In assets/javascripts? But if so, wouldn't that get picked up automatically with a //= require . in the application.js?

@Linus yep, //= require . would bring that script into any page on your site so you'd have to do something like Kenny Grant (use //= require_tree ./global ) or bjg suggested.

This was by far the easiest method for me, I changed //= require_tree . to //= require_directory . in application.js and then created a sub-directory in assets\javascripts. Note that you have to include the new directory in config\initializers\assets.rb to precompile your js by adding the line: Rails.application.config.assets.precompile += %w( new_dir/js_file.js )

Best way to add page specific JavaScript in a Rails 3 app? - Stack Ove...

javascript ruby-on-rails ruby-on-rails-3
Rectangle 27 9

If you don't want to use the asset pipeline or the complex work arounds to get that necessary page specific javascript (I sympathise), the simplest and most robust way, which achieves the same as the answers above but with less code is just to use:

<%= javascript_include_tag "my_javascipt_file" %>

Note: this does require one more http request per include tag than the answers which use content_for :head

javascript_include_tag was exactly what I was looking for, cheers AJP

where do you put "my_javascipt_file"? In assets/javascripts? But if so, wouldn't that get picked up automatically with a //= require . in the application.js?

@Linus yep, //= require . would bring that script into any page on your site so you'd have to do something like Kenny Grant (use //= require_tree ./global ) or bjg suggested.

This was by far the easiest method for me, I changed //= require_tree . to //= require_directory . in application.js and then created a sub-directory in assets\javascripts. Note that you have to include the new directory in config\initializers\assets.rb to precompile your js by adding the line: Rails.application.config.assets.precompile += %w( new_dir/js_file.js )

Best way to add page specific JavaScript in a Rails 3 app? - Stack Ove...

javascript ruby-on-rails ruby-on-rails-3
Rectangle 27 9

If you don't want to use the asset pipeline or the complex work arounds to get that necessary page specific javascript (I sympathise), the simplest and most robust way, which achieves the same as the answers above but with less code is just to use:

<%= javascript_include_tag "my_javascipt_file" %>

Note: this does require one more http request per include tag than the answers which use content_for :head

javascript_include_tag was exactly what I was looking for, cheers AJP

where do you put "my_javascipt_file"? In assets/javascripts? But if so, wouldn't that get picked up automatically with a //= require . in the application.js?

@Linus yep, //= require . would bring that script into any page on your site so you'd have to do something like Kenny Grant (use //= require_tree ./global ) or bjg suggested.

This was by far the easiest method for me, I changed //= require_tree . to //= require_directory . in application.js and then created a sub-directory in assets\javascripts. Note that you have to include the new directory in config\initializers\assets.rb to precompile your js by adding the line: Rails.application.config.assets.precompile += %w( new_dir/js_file.js )

Best way to add page specific JavaScript in a Rails 3 app? - Stack Ove...

javascript ruby-on-rails ruby-on-rails-3
Rectangle 27 9

the application.css and application.js are not regular css and js files (they could be, but they serve a different purpose

both are manifest files which tell the asset pipeline along with sprockets for js

but according to your other questions it seems you are missing a pretty critical piece of the puzzle

Rails mainly works with gems. Gems are pieces of ruby code which you can tell to add to your rails app via bundler

when you add such a gem like the bootstrap gem, it gets installed (by default in the gems library where you have ruby installed - something like Ruby193\lib\ruby\gems\1.9.1\gems)

If you go there and look for the bootstrap gem you will find the css and js files that are included in the app, and also the jquery and jquery_ujs that you include in the manifest file

since the gems get installed alongside rails, rails don't mind where the files are (as long as it knows where they are).

So the manifest file tells rails "Hey, include these file for me, in this specific order" That is why you can include files that you wrote which are in the assets folder and files are included in a gem

If you don't include the files in the manifest but still install the gem that is equivalent to writing a css or js file, placing it in some folder and not telling rails that it exists. When you do tell rails where it is, via the manifest file, it will include it in the asset compilation process and you can access it regularly.

Alternativly, you don't have to use the asset pipeline for assets

you can include css and js file with a regular

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

and just host your files somewhere and point it to the files, but the asset pipeline has many advantages and its really makes your life easier when you get to know it

ruby - Rails - Understanding application.js and application.css - Stac...

ruby-on-rails ruby gem
Rectangle 27 8

the application.css and application.js are not regular css and js files (they could be, but they serve a different purpose

both are manifest files which tell the asset pipeline along with sprockets for js

but according to your other questions it seems you are missing a pretty critical piece of the puzzle

Rails mainly works with gems. Gems are pieces of ruby code which you can tell to add to your rails app via bundler

when you add such a gem like the bootstrap gem, it gets installed (by default in the gems library where you have ruby installed - something like Ruby193\lib\ruby\gems\1.9.1\gems)

If you go there and look for the bootstrap gem you will find the css and js files that are included in the app, and also the jquery and jquery_ujs that you include in the manifest file

since the gems get installed alongside rails, rails don't mind where the files are (as long as it knows where they are).

So the manifest file tells rails "Hey, include these file for me, in this specific order" That is why you can include files that you wrote which are in the assets folder and files are included in a gem

If you don't include the files in the manifest but still install the gem that is equivalent to writing a css or js file, placing it in some folder and not telling rails that it exists. When you do tell rails where it is, via the manifest file, it will include it in the asset compilation process and you can access it regularly.

Alternativly, you don't have to use the asset pipeline for assets

you can include css and js file with a regular

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

and just host your files somewhere and point it to the files, but the asset pipeline has many advantages and its really makes your life easier when you get to know it

ruby - Rails - Understanding application.js and application.css - Stac...

ruby-on-rails ruby gem
Rectangle 27 12

config.generators do |g|
  g.test_framework nil
end

May not be the "most appropriate" or Rails-ish way, but it works

I was reading the Rails Initialization Guide today and realized that the most likely reason Test::Unit is still being included is this line:

require 'rails/all'
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"

This should take care of the issue. If you're using Rails 3.1.x you'd also include

require "sprockets/railtie"

if you're planning on using the asset pipeline.

config.app_generators do |c|
  c.test_framework :rspec, :fixture => true,
                           :fixture_replacement => nil

  c.integration_tool :rspec
  c.performance_tool :rspec
end

I want to remove the current test framework, not replace it?

ruby on rails - Remove test::unit - Stack Overflow

ruby-on-rails ruby-on-rails-3
Rectangle 27 31

Add set :normalize_asset_timestamps, false to your deploy file. By default it's set to true and it runs a touch command on all your images/javascripts/stylesheets but it's no longer needed if you're using the asset pipeline.

Awesome. Thanks. That solved most of the errors! Do you happen to know how I should go about solving the symlink error? [Deprecation Warning] This API has changed, please hook deploy:create_symlink instead of deploy:symlink.

ruby on rails - Missing folder errors during capistrano deploy - Stack...

ruby-on-rails deployment capistrano
Rectangle 27 31

Add set :normalize_asset_timestamps, false to your deploy file. By default it's set to true and it runs a touch command on all your images/javascripts/stylesheets but it's no longer needed if you're using the asset pipeline.

Awesome. Thanks. That solved most of the errors! Do you happen to know how I should go about solving the symlink error? [Deprecation Warning] This API has changed, please hook deploy:create_symlink instead of deploy:symlink.

ruby on rails - Missing folder errors during capistrano deploy - Stack...

ruby-on-rails deployment capistrano