100

In Rails 3, gems used exclusively to generate assets in the asset pipeline were properly placed in the assets group of the Gemfile:

...

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails'
  gem 'coffee-rails'
  gem 'uglifier'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem 'therubyracer', :platforms => :ruby
end

Now, according to the (still in progress) upgrade documentation:

Rails 4.0 removed the assets group from Gemfile. You'd need to remove that line from your Gemfile when upgrading.

Sure enough, making a new project with RC1 yields a Gemfile with asset-related gems included by default outside of any group:

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0.rc1'

# Use sqlite3 as the database for Active Record
gem 'sqlite3'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0.rc1'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

...

Does this mean these gems will now be bundled in production builds by default? If so, why the change of heart? Is Rails 4 moving towards the dynamic generation of assets in production?

jemmons
  • 18,605
  • 8
  • 55
  • 84
  • 1
    I still don't get what the purpose of the "asset group" was, and what changed in Rails 4 that made the asset group unnecessary. – Michiel de Mare Jun 25 '13 at 14:32
  • 23
    The "asset group" was different things to different people. I used it as a place to put gems that I didn't need bundled in production. But judging from the conversation linked to in the accepted answer, at least some people in rails core used it as a way to make sure that non-precompiled assets failed with a 404 in production (instead of silently auto-generating which would lead to poor performance). What changed is rails4 doesn't auto-generate assets anymore, so the "asset group" workaround (as rails core saw it) has been removed. – jemmons Jun 26 '13 at 02:36
  • That's the clearest explanation yet. If you put it in an answer, the bounty is yours. – Michiel de Mare Jun 26 '13 at 11:35
  • @MichieldeMare I'd feel weird getting a bounty for my own question ;-) If you feel like it, you could give the bounty to Filipe Giusti (the accepted answer) as he was instrumental in helping me understand. – jemmons Jun 26 '13 at 14:27
  • But what about gems that you don't want in production, like 'javascript engine' can I put it in 'development group' since I don't really need it in production – eveevans Sep 11 '13 at 21:37
  • 4
    A warning to people in the future: If you choose to ignore the Rails upgrade guide and keep the asset group in your Gemfile, keep in mind that Rails will no longer automatically require the asset group when compiling assets in production. You'll either need to do that yourself, or add `RAILS_GROUPS=assets` (see [`Rails.groups`](http://apidock.com/rails/Rails/groups/class)) before the command to precompile assets in production in your build environment. – Ajedi32 Feb 04 '14 at 17:06

3 Answers3

100

Previously the assets group existed to avoid unintended compilation-on-demand in production. As Rails 4 doesn't behave like that anymore, it made sense to remove the asset group.

This is explained in more detail in the commit that changed that. I extracted some quotes with the actual answer.

Some gems can be needed (in production) like coffee-rails if you are using coffee templates and the fact that now assets are not precompiled on demand in production anymore.

(not precompiled on demand in production) Means that if you have that gems in production environment in 3.2.x and forget to precompile, Rails will do exactly what it does in development, precompile the assets that was requested. This is not true anymore in Rails 4, so if you don't precompile the assets using the tasks you will get a 404 when the assets are requests.

Community
  • 1
  • 1
Filipe Giusti
  • 2,923
  • 3
  • 24
  • 18
  • 32
    Wasn't it also saving memory? Now all gems, even those not needed in "production" (only in precompile), are loaded and thus rails consumes more memory? – gucki Sep 12 '13 at 09:35
  • 3
    +1 @gucki and load time. This was my understanding of the groups.. Since there was already a config option to disable live compile anyway. What does "support" amount to here. afaik my Rails 3 app had a line in env/prod.rb which loaded assets just on development. If that is all, can we just add it anyway? – Karthik T May 25 '14 at 02:54
  • The assets group is removed. Earlier the gems inside assets were loaded into production, now what if we also need them in production. Hence they should be load in production, removal of assets group ensures that. The assets have to precompiled before moved to production. – prashantsahni May 20 '15 at 08:11
13

Rails 4 try to force you to precompile your assets before deployment. You have to precompile your assets with

$ RAILS_ENV=production bundle exec rake assets:precompile

And why? I found this in Guide:

By default Rails assumes that assets have been precompiled and will be served as static assets by your web server.

(Source: http://edgeguides.rubyonrails.org/asset_pipeline.html#in-production)

But many time you have to use these 'assets' gems in production... for example, if you use a js.coffee file in your views directory, then Rails needs coffee compiler in production mode as well.

So I guess, the reason of this change is performance improvement... and looks more simple as well. :)

Zoltan
  • 4,936
  • 1
  • 35
  • 40
  • 22
    Rails assuming that assets have been precompiled is an argument for *keeping* the `assets` group, not getting rid of it (if assets are precompiled, then these gems aren't needed in production and shouldn't be included by bundler). And yes, maybe you would use a gem like `coffee-rails` in production... but that was the case in Rails 3 too, right? And Rails 3 put `coffee-rails` in the `assets` group, by default. So why the change for Rails 4? – jemmons May 30 '13 at 16:32
  • 1
    Why would you use a js.coffee file in your views directory? That should go in assets/javascripts. – Marnen Laibow-Koser Mar 26 '14 at 21:26
3

We want coffeescript with AJAX (history), so coffee-rails moves out of the assets group.
sass-rails misbehaves (history), so it moves out of the assets group.

Axe the assets group.

mockturtl
  • 82
  • 4
  • 2
    CoffeeScript shouldn't be in views. You can do Ajax without that. You don't need to dynamically generate JS in order to do Ajax. In fact, you shouldn't dynamically generate JS. Precompile your CoffeeScript files and avoid the issue entirely. – Marnen Laibow-Koser Mar 26 '14 at 21:27
  • 1
    sass-rails misbehaves because `Bundler.require :assets` is not being run. That's not a rationale to remove assets group. I don't want therubyracer, libv8 et c. on production, why does anybody do? Coffee template can be compiled to a JS template, and there's not point to compile it each time a new value is substituted. There's no point taking all this burden to production. – phil pirozhkov Aug 15 '14 at 12:00