lucasefe / themes_for_rails

Theme Support for Rails 3
This very same page :)
MIT License
309 stars 102 forks source link

error running rake assets:precompile #60

Open kenton opened 12 years ago

kenton commented 12 years ago

I'm running Rails 3.2.1 and themes_for_rails 0.5.1.

Trying to deploy and keep getting errors with precompiling assets.

In trying to narrow down the problem, I'm trying to run rake asset:precompile manually on my local machine, setting RAILS_ENV to production, which gives me the same error as what I see in my capistrano deployment.

Here's the error I keep getting, using the --trace option along with the rake task:

https://gist.github.com/2982787

Any ideas what I'm doing wrong here?

Thanks.

lucasefe commented 12 years ago

Are you using the app in development? Works alright?

The error indicates that you are calling that method on one of your assets. Can you see which is it and provide more context information?


Lucas Efe

On Jun 24, 2012, at 7:46, Kenton Newbyreply@reply.github.com wrote:

I'm running Rails 3.2.1 and themes_for_rails 0.5.1.

Trying to deploy and keep getting errors with precompiling assets.

In trying to narrow down the problem, I'm trying to run rake asset:precompile manually on my local machine, setting RAILS_ENV to production, which gives me the same error as what I see in my capistrano deployment.

Here's the error I keep getting, using the --trace option along with the rake task:

https://gist.github.com/2982787

Any ideas what I'm doing wrong here?

Thanks.


Reply to this email directly or view it on GitHub: https://github.com/lucasefe/themes_for_rails/issues/60

kenton commented 12 years ago

Yes, I'm using the app in dev and it works just fine.

I'm not sure I understand the second thing you mentioned. In my theme, I'm calling theme_stylesheet_link_tag to link to the stylesheet used by that theme. This is the same thing I did before moving to using the asset pipeline. Is that what you're referring to? If not, how do I find out which asset the method is being called on?

lucasefe commented 12 years ago

I had problem while debugging assets pipeline and it was really hard to know what was happening because the rake task doesn't output anything useful.

In order to help you I need more information. What is really weird is that that method is most used on the view files, and the rake task only process asset files like css, or js, and the like. Are you sure you are not using the theme_stylesheet... In a wrong place?


Lucas Efe

On Jun 24, 2012, at 10:54, Kenton Newbyreply@reply.github.com wrote:

Yes, I'm using the app in dev and it works just fine.

I'm not sure I understand the second thing you mentioned. In my theme, I'm calling theme_stylesheet_link_tag to link to the stylesheet used by that theme. This is the same thing I did before moving to using the asset pipeline. Is that what you're referring to? If not, how do I find out which asset the method is being called on?


Reply to this email directly or view it on GitHub: https://github.com/lucasefe/themes_for_rails/issues/60#issuecomment-6533013

lucasefe commented 12 years ago

Also, which assets are you precompiling ?

kenton commented 12 years ago

So my app has a basic setup with /assets and /stylesheets /javascripts and /images in the /assets dir. I also have my /themes dir under /assets. I've followed the instructions on the asset pipeline wiki page for this gem using the "unified theme storage" option.

The "theme_stylesheet_link_tag" error is happening in the application.html.erb layout file for one of my themes. In that layout file, I'm just adding the following to the head section of the page, just like normal:

<%= theme_stylesheet_link_tag "styles", "slider" %>

styles.css and slider.css are in /assets/themes/theme_name/stylesheets/ directory.

Regarding which assets I'm precompiling, not sure how to answer that. I'm not specifying any assets in particular, just running the rake task mentioned earlier. So my guess is that it's trying to precompile all assets.

Does any of that help?

Let me know if I missed something.

jayroh commented 12 years ago

Running into the same issue here. We went the way of the unified approach and have our themes in APP_ROOT/app/assets/themes/<theme names>.

Our themes for rails initializer looks like so:

ThemesForRails.config do |config|
  config.themes_dir = ":root/app/assets/themes"
  config.assets_dir = ":root/app/assets/themes/:name"
  config.views_dir =  ":root/app/assets/themes/:name/views"
  config.themes_routes_dir = "assets"
end

And when we run the precompile rake task:

✗ rake assets:precompile --trace
** Invoke assets:precompile (first_time)
** Execute assets:precompile
/Users/joel/.rvm/rubies/ruby-1.9.3-p194/bin/ruby /Users/joel/.rvm/gems/ruby-1.9.3-p194@global/bin/rake assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets --trace
** Invoke assets:precompile:all (first_time)
** Execute assets:precompile:all
** Invoke assets:precompile:primary (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
** Invoke tmp:cache:clear (first_time)
** Execute tmp:cache:clear
** Execute assets:precompile:primary
rake aborted!
undefined method `theme_stylesheet_link_tag' for #<#<Class:0x007f8672956bb8>:0x007f8671d7f970>
  (in /Users/joel/Development/ApplicationName/app/assets/themes/our_theme/views/layouts/application.html.erb)

Previously we had had all the themes in APP_ROOT/themes and things worked fine but needed to shuffle things around. I can't help but shake the feeling it's something we're not quite hitting in the initializer config. Any pointers?

lucasefe commented 12 years ago

Your configuration is not the problem, since I use this:

ThemesForRails.config do |config|
  config.themes_dir = ":root/app/assets/themes"
  config.assets_dir = ":root/app/assets/themes/:name"
  config.views_dir =  ":root/app/views/themes/:name"
  config.themes_routes_dir = "assets"
end

The method that is failing is not being included when running the precompile task. I'm looking into it right now.

lucasefe commented 12 years ago

Ok, I'm testing this in a brand new rails application (3.2.5) [1] and it works.

What I did was the following:

Please, @jayroh and @kenton, can you verify if this app works for you? And also, if you did the same steps?

Thanks

[1] git://github.com/lucasefe/themes_for_rails_sample.git

gabebw commented 12 years ago

@lucasefe - I'm working on the same app as @jayroh. We ran into a problem with "Unified Theme Storage", on this wiki page, where the views are under app/assets/theme/THEME_NAME. With unified themes, the assets pipeline tries to precompile the views, since they're under app/assets. We've moved to split theme storage (like your configuration for the sample app linked above), and everything works fine.

Do you mind if I edit the wiki to add a warning for people not to put their views under app/assets?

lucasefe commented 12 years ago

How would I mind, man? Thanks!

gabebw commented 12 years ago

Looks like I spoke too soon. The assets are being compiled correctly (i.e. they are in public/assets/THEME/stylesheets/* etc), but I cannot access them in the browser (localhost:3000/assets/THEME/stylesheets/application.css) - I get a "404". Weirdly, I can access images: localhost:3000/assets/THEME/images/whatever.png.

This is in a production environment.

This is what our directory structure looks like:

initializer:


ThemesForRails.config do |config|
  # themes_dir is used to allow ThemesForRails to list available themes. It is not used to resolve any paths or routes.
  config.themes_dir = ":root/app/assets/themes"

  # assets_dir is the path to your theme assets.
  config.assets_dir = ":root/app/assets/themes/:name"

  # views_dir is the path to your theme views
  config.views_dir =  ":root/app/views/themes/:name"

  # themes_routes_dir is the asset pipeline route base. 
  # Because of the way the asset pipeline resolves paths, you do
  # not need to include the 'themes' folder in your route dir.
  #
  # for example, to get application.css for the default theme, 
  # your URL route should be : /assets/default/stylesheets/application.css
  config.themes_routes_dir = "assets" 
end

Relevant section of config/application.rb (everything else in the file is unchanged from the generated Rails app):

  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    config.autoload_paths += %W(#{config.root}/lib)

    # Only load the plugins named here, in the order given (default is alphabetical).
    # :all can be used as a placeholder for all plugins not explicitly named.
    # config.plugins = [ :exception_notification, :ssl_requirement, :all ]

    # Activate observers that should always be running.
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    config.time_zone = 'Eastern Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Configure sensitive parameters which will be filtered from the log file.
    config.filter_parameters += [:password]

    # Use SQL instead of Active Record's schema dumper when creating the database.
    # This is necessary if your schema can't be completely dumped by the schema dumper,
    # like if you have constraints or database-specific column types
    config.active_record.schema_format = :sql

    # Enforce whitelist mode for mass assignment.
    # This will create an empty whitelist of attributes available for mass-assignment for all models
    # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
    # parameters by using an attr_accessible or attr_protected declaration.

    # production app is readonly, so this is unnecessary
    config.active_record.whitelist_attributes = false

    # Enable the asset pipeline
    config.assets.enabled = true

    # Version of your assets, change this if you want to expire all your assets
    config.assets.version = '1.0'

    # Required, otherwise Rails doesn't precompile the files, but does copy them - so you get sprockets directives
    # in assets/application.js
    Dir[Rails.root.join('app/assets/themes/*')].each do |theme_dir|
      config.assets.paths << theme_dir
    end

    # for heroku
    config.assets.initialize_on_precompile = false
    config.assets.precompile += ['active_admin.js', 'active_admin.css']

    # Configure generators
    config.generators do |g|
      g.template_engine :haml
      g.test_framework :rspec
    end
  end
lucasefe commented 12 years ago

Can you paste your Gemfile file too? One time I was switching from Jammit to Sprockets (which is what rails uses to handle static assets) and forgot to remove jammit, so it was in the middle of the request.

Btw, did you restarted the app after moving the folders and everything? Sprockets builds the path list at boot time.

gabebw commented 12 years ago

Yup, restarted the server multiple times. Gemfile (with some private gems removed):


source 'https://rubygems.org'
ruby '1.9.3'
# source 'https://gems.gemfury.com/BHDU4RpkR6GnJDGbBUDr/'

gem 'activeadmin'
gem 'activeadmin_sortable', '0.0.1.pre'
gem 'activerecord-postgres-hstore', github: 'softa/activerecord-postgres-hstore'
gem 'active_admin_editor'
gem 'acts-as-taggable-on', '~> 2.3.1'
gem 'ancestry', '~> 1.3.0'
gem 'aws-s3', require: 'aws/s3' # for viddler import
gem 'bcrypt-ruby', '~> 3.0.0' # To use ActiveModel has_secure_password
gem 'bourbon'
gem 'devise'
gem 'domainatrix'
gem 'flutie'
gem 'friendly_id', '~> 4.0.7'
gem 'haml-rails'
gem 'high_voltage'
gem 'htmlentities'
gem 'jquery-rails'
gem 'meta_search'
gem 'net-sftp', require: 'net/sftp' # for viddler import
gem 'paper_trail', '~> 2.6.3'
gem 'pg'
gem 'rails', '3.2.6'
gem 'rails3-jquery-autocomplete'
gem 'ranked-model'
gem 'strip_attributes', '~> 1.1'
gem 'swiftype-rb', github: 'swiftype/swiftype-rb', require: 'swiftype'
gem 'themes_for_rails', '0.5.1'
gem 'viddler-ruby', '~> 0.1.2' # for viddler import

group :assets do
  gem 'coffee-rails', '~> 3.2.1'
  gem 'sass-rails',   '~> 3.2.3'
  gem 'uglifier', '>= 1.0.3'
end

group :development do
  gem 'tiny_tds'
end

group :development, :test do
  gem 'rspec-rails', '2.10.1'
  gem 'activerecord-sqlserver-adapter', '~> 3.2.4'
  gem 'hashie'
  gem 'rails_best_practices', require: false
  gem 'evergreen', require: 'evergreen/rails'
end

group :test do
  gem 'bourne', '1.0'
  gem 'capybara', '1.1.2'
  gem 'factory_girl_rails', '3.4.0'
  gem 'shoulda-matchers', '1.2.0'
  gem 'simplecov', require: false
  gem 'launchy'
  gem 'capybara-webkit'
  gem 'database_cleaner'
end
rlanvin commented 12 years ago

I had the same issue with the "Unified Theme Storage" folder structure. It tries to precompile the templates, because they are under the /assets folder, and of course it fails. Reverting to split storage solved the issue, as @gabebw noted.

Another related problem I ran into, which might be related to @gabebw problem, is that the CSS and JS files of the themes are actually not precompiled. This is because because by default it ignores any CSS/JS file other than "application.css" and "application.js" (more info here: http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets).

I ended up manually adding all the manifest of each theme to config.assets.precompile. This is done by adding the following code to config/application.rb:

    Dir[Rails.root.join('app/assets/themes/*')].each do |theme_dir|
        config.assets.precompile << "#{theme_dir.split('/').last}/stylesheets/theme.css"
    end

So far it seems to work... but of course it means that I have to have a "theme.css" file for each theme, otherwise it won't compile anything and the theme won't work.

jasherai commented 12 years ago

NOTE: deductions through research. I'm about to test my comments and will update accordingly, but incase it helps others.

We need to remember that asset pipeline will use the first instance of a file it finds to add to the digest. so where you are appending to the assets.path it will be loaded after the default app/assets which is configured by default in rails.

I believe you will see different results if you prepend the path. This also explain why having the unified theme layout works differently.

Looking into how asset pipeline is working, the asset path is split into 2 from theme asset path you add to assets.path

:root/themes/:theme_name/assets/javascript/application.js => javascript/application.js

the second part (referred to as logical path) is stored in the digest and used to look up the actual asset. This is obviously going to clobber subsequent themes as their application.js will have the same logical path.

My next exploration is whether an asset can be added to the digest with a prefix to the logical_path

:root/themes/:theme_name/assets/javascript/application.js => :theme_name/javascript/application.js

and whether this can be done programmatically in TFR.

Obviously you could restructure you directories to be:

:root/themes/:theme_name/assets/:theme_name/javascript/application.js

which would namespace the logical path but is a bit messier in structure, but then convention over configuration?

WRT: precompile failures, you may have better luck if you ensure config.assets.initialize_on_precompile is true in application.rb. NOTE: initialize_on_precompile is enabled by default, however disabling it would make precompilation faster (although broken when using TFR)

I hope my ramblings shed some light or point people in the right direction.. I'll report back what I can.