Rails 3.2 and Sass not rendering Application.css - ruby-on-rails

I just did a major upgrade to Rails 3.2 and the newest Sass and Coffee Rails Gems, but my Application file won't render as Application.css.scss. I had it in my html as such:
<%= stylesheet_link_tag 'application.css.scss' %>
And when I look at the Page Source in my Development mode I'm getting
<link href="/assets/application.css.scss.css" media="screen" rel="stylesheet" type="text/css" />
What the heck is going on!?
It seems to append .css to everything I put inside the stylesheet_link_tag, so if i leave it as just 'application' in my page source I have application.css, etc.

The appropriate format for the tag is:
<%= stylesheet_link_tag 'application' %>
Rails automatically compiles the .scss file into a .css file -- then it automatically imports the correct file. It's all take care of for you.

If you don't append an extension to stylesheet_link_tag, .css will be appended automatically. I do not know why it's appending the extension when you are specifying .scss, however.
I'm also not sure why you don't just use <%= stylesheet_link_tag 'application' %>, which should be all that's necessary.
See the documentation for stylesheet_link_tag here for more info.

I think the "default" way to do this in Rails 3.2 using Sprockets is to have file called application.css (not application.css.scss) that contains your Sprockets manifest code. Which should look something like this...
application.css (app/assets/stylesheets)
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. 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.
*= require_self
*= require main_scss_file
*/
There should be at least two lines one should be the require_self which adds the content inside itself and the require some_other_file which is a reference to your main scss file.The default behavior of rake assets:precompile is to compile your application.js and application css
production.rb coded generated by Rail generators specifies that application.css is compiled by default. (config/environments)
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
config.assets.precompile += %w( home.js )
application.erb
<%= stylesheet_link_tag 'application' %>

Related

Rails CSS stylesheets overriding each other

I have a clients.css and jobs.css in the assets/stylesheets location.
Each has a respective controller. Jobs was created with a scaffold after clients. The scaffolds.scss file is blank.
application.css is blank
When I code a change such as body{color:black} in the jobs.css, it changes the clients/index.html.erb view and the jobs/index.html.erb view.
What could be the reason for this? I would like to have separate .css files for jobs and clients..
From the documentation:
Sprockets concatenates all JavaScript files into one master .js file
and all CSS files into one master .css file.
What this means, of course, is that when you make a change to jobs.css, you'll see the same css being applied to every matching element throughout your application. All of those separate .css files are there to help you keep things organized from a human perspective, rather than from the perspective of your application.
You might want to just come up with different IDs and classes depending on your page (like #body_client and #body_job) to differentiate them, but you can see how this naming convention could get unwieldy as your app grows.
Having separate assets is possible, but not without some pain.
In application.js, remove:
//= require_tree
In application.css, remove:
*= require_tree
In application.html.erb, add the following:
<%= stylesheet_link_tag "application", params[:controller], :media => "all" %>
<%= javascript_include_tag "application", params[:controller] %>
Create a new initializer file at config/initializers/assets.rb and add the following code:
%w( clients_controller jobs_controller ).each do |controller|
Rails.application.config.assets.precompile += ["#{controller}.js.coffee", "#{controller}.css"]
end
That should get you set up with separate per page assets. Check the original blog post for more details.

Pages without application.html.erb

I am developing my first ruby on rails web application at the moment and I have a little bit of a problem. I would need two pages (a start page and a login page) which haven't the application.html.erb layout.
At the moment I gained that by adding:
layout false
To my login_controller.rb file. But now I am unable to use the twitter bootstrap components which i included in the /assets/stylesheet and /assets/javascripts folder.
Can someone show me a best practice method how to add pages without the layouts and design from the application.html.erb, but still can use the twitter bootstrap components?
You can create a different layout file including only the assets you need.
A typical scenario I usually face is the administration section of a web site where the layout changes from the public section.
In that case you can create a layout views/layouts/admin.htm.erb like this:
<!DOCTYPE html>
<html>
<head>
<title>Admin</title>
<%= stylesheet_link_tag "admin", :media => "all" %>
<%= javascript_include_tag "admin" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
As you can see there are two different manifest files for the js and css assets.
That means there are two files:
/assets/javascripts/admin.js
/assets/stylesheets/admin.css
Like in the application.js and application.css you can require bootstrap and other assets you may need for that specific layout.
Here an example:
/*
* 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.
*
*= require bootstrap
*= require_self
*/
The last thing
You need to tell rails to precompile the new manifest files you created.
In /config/environments/production.rb
# Precompile additional assets (application.js.erb, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
config.assets.precompile += %w( admin.css admin.js )
NOW YOU CAN USE THE LAYOUT
In your controller:
layout "admin"

Rails! How to have styles appear last instead added to application.css

Im a newbie to Ruby and Rails and wanted to know how to add custom.css to be last css file call in DOM.
Also, if I need Js to be last and not above the header, what's the correct way of doing this.
Currently everything coming from the assets folder in Rails order.
Thanks...
You can add:
<%= stylesheet_link_tag "custom", :media => "all" %>
to the bottom of the layouts file and add custom.css to your precompile list:
# /config/environments/production.rb
config.assets.precompile += %w( custom.css )
But your application.css file will still compile with custom.css.
You can stop it compiling in application.css by setting which files are included in the application.css file. Change,
# /app/assets/stylesheets/application.css
/*
*= require_tree .
*/
to
/*
*= require first_css
*= require second_css
*/
which will ignore the custom.css file. It's very similar for the javascript. See http://guides.rubyonrails.org/asset_pipeline.html for more info.
In your layout.erb you can include everything you need under your layout itself

when do I need to add an asset to config.assets.precompile and when not?

I'm a little confused by when I need to add an asset to config.assets.precompile and when it's not necessary.
(It's possible that my problem may stem from the fact that this app was migrated from rails 2.x; at some point soon I'm going to rebuild it from the ground up as a 3.x app, but don't have the time for that yet.)
Here's my issue: I have a .css and .js files that are not being found by sprockets unless I add them to config.assets.precompile in application.rb. I can't imagine I have to do this for every .js and .css, do I?
For example, one file I'm having this issue with is app/assets/stylesheets/facybox.css.
application.css is:
/*
*= require_self
*= require_directory .
*/
(yes, require_directory instead of require_tree intentionally).
I run rake assets:precompile on my server during deploy. The resulting application.css has the contents of facybox.css in it.
facybox.css is referred to in a partial, like this:
<% content_for :header do %>
<%= stylesheet_link_tag "facybox" %>
<% end %>
But when I go to a page that includes the partial, I get:
Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError in Admin#compositions
Showing /srv/zmx/releases/5420c4dde6fbec53d78cffe78396085f263ed039/app/views/shared/_preview_assets.erb where line #6 raised:
facybox.css isn't precompiled
which I assume is because sprockets is looking for the fingerprinted copy of the file, which doesn't exist unless I add it to config.assets.precompile. Then all is hunky-dory.
Can someone explain?
The rules for precompiling are simple:
If an asset is required in one of the application manifests you do not need to add it to precompile.
If an asset needs to be referenced directly in a Rails view then you DO need to add it (and you should remove it from any manifests).
As you said yourself, the contents of facybox.css are already included in your application.css.
This means that you can just remove the stylesheet_link_tag from your partial and also any other places where you use facybox.css. You would have to do the same for all other stylesheets that you already have included in your application.css

Ignore file with CSS manifest?

I was wondering if there was a way to ignore a css file from being added to the manifest application.css file.
The reason why I want to do this is that I have two versions of the site, a mobile version, an an web version. The mobile version's css is currently being added to the manifest, and messing with the style of the main page.
Is there anyway to configure the manifest file to exclude a certain css file?
Remove the require_tree directive and add just the files you want, in the order you want them to application.css. Leave out the mobile CSS file.
To access the mobile CSS file you need to add it to the precompile list in
production.rb:
config.assets.precompile += ['mobile.css']
This will allow you to use the standard rails helper to access the mobile css:
<%= stylesheet_link_tag "mobile" %>
as distinct from the application.css file.
One tip for these situations is that you can share CSS files between manifests. For example, if you have a CSS reset in a separate file this can be added to both manifests (assuming you make the mobile css a manifest too).
What I ended up doing was creating subdirectories under app/assets/stylesheets called app/assets/stylesheets/web and app/assets/stylesheets/mobile
Then place an application.css with the standard:
/* ...
*= require_self
*= require_tree .
*/
inside each of your new web and mobile folders. Then to access them:
# just use this
<%= stylesheet_link_tag "web/application", :media => "all" %>
# or this as needed
<%= stylesheet_link_tag "mobile/application", :media => "all" %>

Resources