Rails 3.1 assets pipeline in production
Asked Answered
U

4

6

I am using the assets pipeline (in Rails 3.1.3) and am kind of struggling to make it work in production.

Situation

In my /app/assets/stylesheets directory I have the following files:

application.css --> this is the default rails one
stylesheet.css --> This is my custom stylesheet

I spent a lot of time getting my stylesheet.css included in the /public/assets/directory in production (by running rake assets:precompile) and I finally made it by adding the following line into in my application.rb file:

    config.assets.precompile += ['stylesheet.css']

I know have the right precompiled stylesheet.css file in production.

My Problem

The problem I have is when using stylesheet_link_tag with my stylesheet.css file. It turns out:

<%= stylesheet_link_tag "stylesheet" %> is resolved into <link href="/stylesheets/stylesheet.css" media="screen" rel="stylesheet" type="text/css"> in production I would expect the path to be resolved into /assets/stylesheet.css just like it does in development.

What is even more surprising is that application.css behaves perfectly even though <%= stylesheet_link_tag "application"%> resolves into <link href="/stylesheets/stylesheet.css" media="screen" rel="stylesheet" type="text/css">. What I don't understand is that the public/stylesheets/ directory does not exist in rails 3.1.

Any idea ?

Unlive answered 6/1, 2012 at 15:42 Comment(1)
The only solution I have found so far is using <%= stylesheet_link_tag "/assets/stylesheet.css" %>. It is not satisfying but it works !Unlive
U
8

Richard Hulse answers pointed me to the right direction. What happens is really subtle..

The answer to my question is Rails 3.1 assets has no fingerprint in production.

Basically, my project use mongoid instead of ActiveRecord. According to Mongoid documentation about configuration, the application.rb file can be modified to not include ActiveRecord which means removing:

require railties/all

And replacing it with:

require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
# require "sprockets/railtie" # Uncomment this line for Rails 3.1+

I was so used to doing this manipulation with rails 3.0.x that I did not pay attention to the comment related to Rails 3.1

My problem was that I was not requiring sprockets !

Thank you all for your help !

Unlive answered 8/1, 2012 at 13:42 Comment(0)
G
7

The reason you can access stylesheet.css in development is because of how Sprockets works.

In development mode ALL requests to anything under /assets are sent to Sprockets to process. Sprockets will directly map requests to paths, one-to-one, so you can access any assets stored in app/assets/etc.

All requests go through Sprockets; it is serving the files to your browser.

In production things are different. A fingerprint is added to filenames, and the expectation is that you'll precompile your assets to static files. This is for performance reasons - Sprockets is not fast enough to serve lots of requests.

Only those CSS and JS files referenced by the default manifests are compiled into application.css and application.js. Other files that you reference are not precompiled unless they are added to the config.assets.precompile array in your config file.

You say that the files resolve to /stylesheets/stylesheet.css. The pipeline should generate a path like this in development: /assets/applicaton.css. In production there should be a fingerprint in the filename. What you have posted suggested that the pipeline is not enabled (these are the old, pre 3.1, locations for the files).

If this is an upgraded app, it is likely that you have missed some crucial config option. This is the main cause of dev->production issues. Check that the pipeline options are set exactly as they are in the last section of the pipeline guide. (My guess is that you are missing config.assets.enabled = true in application.rb)

And for clarity I would suggest changing the name of stylesheet.css to admin.css, while including this in the precompile array (as you already had done).

With the config options set correctly, and your admin manifest included in precompile, you should have application.css available for the front end and admin.css available for the back-end, both linkable via the helper methods.

Glottis answered 8/1, 2012 at 4:27 Comment(3)
What you are saying makes a lot of sense. However, I do have the config.assets.enabled = true instruction in my application.rb file. And this app is fresh rails 3.1.3 app. I will try to further investigate my issue since as you are saying it really looks like the assets pipeline is not enabled in production (fingerprint missing)Unlive
Ok I got it ! Wrote another answer about this. I am using mongoid and I was actually not including sprockets ! This question pouted me to the right direction: #7648849Unlive
Yeah, that one will get you every time! ;-)Glottis
P
1

You application.css should be a manifest file, meaning that your when you run your program it should include your stylesheet.css automatically.

make sure it has these two lines.

application.css:

/*
 *= require_self
 *= require_tree . 
*/

If it does then something else isn't working properly, you shouldn't need the line:

config.assets.precompile += ['stylesheet.css']

If that isn't working either make sure you have all the settings enabled from this Asset Pipeline guide.

Pint answered 6/1, 2012 at 16:25 Comment(3)
What I am looking for is to not include the application.css file. This is the reason why I am using another css file. The reason for that is that I want to have different css files depending on whether I am in the front office or the back-officeUnlive
Then I'm a little confused, does your application.css still have the manifest above? Or does stylesheet.css? If either do can you post the manifest?Pint
application.css does not have such a broad manifest. It does not have the require_tree . directive. Instead it has a require_tree ./admin because I am only using it for my back officeUnlive
P
0

While I was looking around actionpack to see what might be causing this problem I found this little gem in the 3.1.1 changelog:

javascript_path and stylesheet_path now refer to /assets if asset pipelining is on.

Soooo, If you're using 3.1.0 upgrade to 3.1.1 and see if it fixes it. If you've already upgraded then were back to square one. But it does seem to describe your problem since stylesheet_link_tag uses stylesheet_path interally.

Pint answered 8/1, 2012 at 3:21 Comment(1)
I updated my question. This app is a rails 3.1.3 app. Thank you for the tip anywayUnlive

© 2022 - 2024 — McMap. All rights reserved.