Asset names passed to helpers should not include the "/assets/" prefix - ruby-on-rails

I have a rails app in production with apache2 and passenger. But some of my images didn't appeared so i changed the path inside the 'image_tag' like this:
<%= link_to image_tag("/assets/#{product.image_url}", {:title => "Push it into cart!"}), line_items_path(product_id: product), method: :post %>
After this all work fine in production. But when i try in development, i got this error:
Sprockets::Rails::Helper::AbsoluteAssetPathError in Store#index
Asset names passed to helpers should not include the "/assets/" prefix. Instead of "/assets/cs.jpg", use "cs.jpg"
What i should do to make it work in both enviroments?

image_tag works without using /assets/ path as long as you have the asset pipeline enabled (which is the default) and your image is in app/assets/images/ folder. If your image is outside that folder it won't get precompiled so you'll have to add it to the asset precompilation, in your config/environments/production.rb add
config.assets.precompile += ['image.jpg']
I think that for your problem you shouldn't store the images of your products in the assets folder as this is used for the application images not for you content (models) images, those should be stored in the public folder public/uploads is commonly used for that by gems like paperclip

You should never use /assets/ prefix, it's possible that you just need to precompile assets for production.
rake assets:precompile RAILS_ENV=production
It also depends on where are you using the said asset, for example, when using it in stylesheet you should use image-url('image.jpg') rails css helper. When using it inline in the view, you use the image_tag helper, as you have.

Related

How can I have assets compiled into image, stylesheet, and javascript directories?

The asset pipeline puts everything into the same directory. Images, stylesheets, and javascripts all go into /public/assets (although subdirectories are respected).
Is there a way to have them copied into /public/assets/images, public/assets/stylesheets, and public/assets/javascripts?
Adding to the confusion is this line in the rails guide:
http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets
In regular views you can access images in the public/assets/images directory like this:
But rails doesn't use or make a public/assets/images directory.
Solution #1:
Create a new subdirectory within the app/assets/ like all and move the
current asset directories into that the new folder; e.g.
mkdir -p app/assets/all
mv app/assets/{javascripts,images,stylesheets} app/assets/all/
Then when precompiling assets with RAILS_ENV=production rails assets:precompile
it should create those javascripts, images and stylesheets directories
underneath the public/assets directory;
public/assets/javascripts
public/assets/images
public/assets/stylesheets
Solution #2:
You can create a new directory somewhere else in your project; like assets,
instead of app/assets; and add that the new directory to the current Rails
asset paths configuration within the assets.rb initializer
# app/config/initializers/assets.rb
Rails.application.config.assets.paths << Rails.application.root.join("assets")
Then precompiling assets should have the same effect as Solution #1.
Solution #3
So, as part of the Sprocket-Rails Engine it preloads the app/assets
subdirectories with this following block of code:
# ~/ruby/gems/2.3.0/gems/sprockets-rails-3.2.0/lib/sprockets/railtie.rb:54
module Rails
# [...]
class Engine < Railtie
# Skip defining append_assets_path on Rails <= 4.2
unless initializers.find { |init| init.name == :append_assets_path }
initializer :append_assets_path, :group => :all do |app|
app.config.assets.paths.unshift(*paths["vendor/assets"].existent_directories)
app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories)
app.config.assets.paths.unshift(*paths["app/assets"].existent_directories)
end
end
end
end
The line of interest is the
app.config.assets.paths.unshift(*paths["app/assets"].existent_directories)
It call to existent_directories off the *paths["app/assets"] is returning
all the subdirectories within the assets folder, hence why there are no
subdirectories in the public/assets folder when Sprocket computes its digested
assets.
In order to add those sub-directories back in, we have to modify the current
Rails configured environment for Sprockets; i.e.
Rails.application.config.configure. However, the Sprockets::Paths that is
included in the Sprockets::Configuration that
Rails.application.config.configure yields to does not allow public access to
its internal #paths variable, nor does it have an method to remove paths like
it does to add paths via its append_paths. Instead we have to duplicate the
current paths already included by the above Railtie initializer block, remove
the old "app/assets" subdirectories paths that we do not want, add in just the
"app/assets" directory we do want and then append them back into the configured
Sprockets environment; which looks something like this in a Rails initializer:
# app/config/initializers/assets.rb
Rails.application.config.assets.configure do |env|
old_paths = env.paths.dup
new_paths = old_paths - Rails.application.paths["app/assets"].existent_directories
new_paths << Rails.application.root.join("app", "assets")
env.clear_paths
new_paths.each { |path| env.append_path(path) }
end
Closing Comments
Using any of these solution should also mean that you will need to specify the subdirectory in all your
asset_path method calls within your view templates in order to find the
compiled asset; e.g.
<%= asset_path "images/example.png" %>
<%= asset_path "javascripts/application.js" %>
<%= asset_path "stylesheets/application.css" %>
/assets/images/example-ca63e56ac855bdfb187479a35a7476cd65c539727f84fea19e1ad258cf3d23f5.png
/assets/javascripts/application-a4f3e75c7f7aa6d6cbc2ebcbb436b12aca442553219883805baebdd2eecd5471.js
/assets/stylesheets/application-539757f75200b6ea43399bf5e25cbc2819c1e6a610f94d5c9beaf91fec89384e.css
I hope one these solutions help.

Rails asset pipeline doesn't serve images

My Rails app doesn't serve images at all.
image_url('picture.jpg')
# will result in url(http://localhost:3000/images/picture.jpg)
# but should be url(http://localhost:3000/assets/picture.jpg)
image_tag 'picture.jpg'
asset_url 'picture.jpg'
# will result in the same url / path as image_url()
Neither http://localhost:3000/images/picture.jpg nor http://localhost:3000/assets/picture.jpg exists, while http://localhost:3000/assets/images/picture.jpg does.
Here is a gist of my application.rb and development.rb: https://gist.github.com/maximski/1ccb75f6f89c02932239
I am in development environment and I don't want to precompile files manually. The app is pretty much much newly generated so the configuration is almost completely set on default.
This problem appear if images doesn't exists in app/assets/images directory. Check that app/assets/images/picture.jpg file is exists.

How do I call images in a subdirectory? Rails 4 app breaks when I push to production

I have a rails app that performs fine in development but as soon I as I push to production it breaks. It was working fine until I added a /gifs subdirectory to the /images directory.
I'm pulling a random gif in the directory and displaying it.
<%= image_tag "assets/gifs/#{rand(10)}.gif" %>
I've also tried
<%= image_tag "gifs/#{rand(10)}.gif" %>
and
<%= asset_url("gifs/#{rand(10)}.gif") %>
But nothing is working. How should I structure this?
Have you tried /assets? Like this:
<%= image_tag "/assets/gifs/#{rand(10)}.gif" %>
I would start without the interpolation just to make sure you can see the image and then add the variable.
EDIT: Sorry for the quick shot, I have it like this in mine and thought that might fix it. I think what you actually need is to tell your config/environments/production.rb that you want to precompile those folders also... in development, it will happily include everything for you, but in production, it needs to be more selective and rigid (there are various explanations for that elsewhere).
Try this:
open config/
look for this line: config.assets.precompile and add your subfolder to it.
config.assets.precompile += [ 'gifs/*.gif']
If you decided to organize your other assets into controller-related subfolders (I like that), you need to add those here too: (example: local, resources, projects, shared subfolders)
config.assets.precompile += [ 'local/*.css', 'resources/*.js', 'projects/*.js', 'shared/*.js', 'ui/*.js', 'admin.a pp.js', 'jquery.tablesorter.min.js', 'date-picker.js', 'date_extras.js', 'jquery.tablesorter.min.js']
Hope this helps!

Rails routes for non-standard assets in a mountable engine

I have a few non-standard assets (i.e. files that are not images/javascript files/stylesheets such as json and binary files) that live within a mountable engine (without isolate_namespace) in app/assets/data. I want these to be part of the asset pipeline (in the same way as e.g. images).
I can add them to the asset paths collection, e.g.
class Engine < ::Rails::Engine
config.after_initialize do
Rails.application.config.assets.paths << root.join("app", "assets", "data")
end
end
and I can see in the Rails console that the assets are visible to the asset pipeline (e.g. via Rails.application.assets[] and ActionController::Base.helpers.asset_path). For instance, for a file app/assets/data/foo.json, the asset_path helper in the rails console for the hosting app gives me a path assets/foo.json, however that path does not work, I get a
ActionController::RoutingError (No route matches [GET] "/assets/foo.json")
error.
How can I get the hosting Rails app to serve these files?
Turns out, this is some odd behavior with json files with specific names. The files in question are named something like schema-[UUID].json. Rails seems to think these are calls to some controller (even though there is no such route, nor a schema controller) that want json-formatted data back. When I rename the files to [UUID]-schema.json, they all of a sudden work.

Rails 3: Scopes: Routing: JS/CSS helpers

I want to run my Rails application in a different scope so that I can deploy it in a war file (mydepartment.war) which will share a Tomcat instance with another Java app WAR. The solution I chose was to modify the rackup file (/config.ru).
map '/mydepartment' do
run Myapp::Application
end
When I do this, my base URL becomes http://localhost:3000/mydepartment instead of just http://localhost:3000. The application runs fine, but it doesn't download CSS/JS specified by stylesheet and script helpers.
However, when I try to include stylesheets and Javascript using helpers, such as
<%= stylesheet_link_tag :all %>
<%= javascript_include_tags :defaults %>
The URLs they generate include localhost:3000/javascripts/jquery.js instead of localhost:3000/mydepartment/javascripts/jquery.js. I actually tried typing the latter in the browser, and the sheet downloads fine.
How can I coax the Rails Javascript/CSS helpers to download files in the new scope without hardcoding it?
if you're not on rails 3.1:
Add this to your config/environments/production.rb (if on production mode):
config.action_controller.asset_path = proc { |path| "/mydepartment#{path}" }

Resources