I have some doubts about the folders on which I should put the public files.
We got at the root path a folder called public and some other folders in app (rails 5.0.1 for me), let me show you the ones which sound strange for me:
app/assets/ (images | javascripts | stylesheets)
app/views/pages
After reading multiple tutorials and existing public projects, I saw that some people put his web template in public (js, css and images included).
Yet, in my case, because of I have seen it few times too and found it logic, I have put my template in assets separating my js, sass (in my case) files, and images in the folders already created by the RoR generator.
Additionnal, it seems logic for me to put my files in assets because my main layout gonna take my template files in assets with the framework default API. The following line works for me and gonna load my app/assets/stylesheets/ app.css.scss file
<%= stylesheet_link_tag 'app', media: 'all', 'data-turbolinks-track': 'reload' %>
Hope someone could explain what's the better way, I'm beginner with Rails, thanks.
app/assets/
This is where you put custom assets (images, js/css scripts that you own and custom to your application)
vendor/assets/
This is for third party libraries that you use in your app (carousel js plugin, etc)
.
├── app
│ ├── assets (custom assets specific to your app)
├── public (static-files like error pages, favicon, etc which does not change much)
├── vendor
│ └── assets (third party libraries that your app uses)
Precompiled Assets
Add all the paths to your assets (images, js/css files) used in your application in assets precomile path in config/initializers/assets.rb (application.css and application.js are included by default)
All the assets when precompiled with
bundle exec rails assets:precompile
This generates public/assets directory with all the assets configured in your precompile path as readily servable static assets which are then served to your application responses.
Related
In a new default Rails 7 application using the import maps functionality, Javascript is stored in app/javascript, while CSS is located in app/assets/stylesheets. Not only are they located at different hierarchy levels, but javascript is singular, while stylesheets is plural.
I'm looking for sources that explain these divergent locations and pluralization decisions. Searches through Rails Guides and API documentation have turned up nothing, but support talk on the Rails repo suggests that docs are still being actively updated.
On the surface this seems really shortsighted, but I want to make sure I'm not missing something before I go messing with the defaults.
app/assets is used by sprockets. This is rails asset pipeline. Preprocessing, minification, compilation etc. app/assets/javascripts was a thing before javascript took over the world, and had to be given its own separate directory.
app/javascript was used by webpacker to avoid mixing it with sprockets processing. This is javascript pipeline that does what sprockets does, process, compile, minify etc. A way to bring javascript build tools into rails. Singular referring to "javascript" language not "javascripts" as in collection of js files (I guess).
Both of these directories can have css and js assets, just processed and compiled by completely different tools.
In rails 7, app/javascript is used by jsbundling-rails that comes with different js build tools, like, esbuild and webpack. After javascript is done its job, bundles go into app/assets/build where sprockets treats it as any old js or css file.
With importmaps there is really no processing but app/javascript is the logical place for it. To use importmaps, all the files in app/javascript have to be precompiled by sprockets for use in production:
// app/assets/config/manifest.js
//= ../../javascript .js
and app/javascript has to be in Rails.application.config.assets.paths:
config.assets.paths << Rails.root.join("app/javascript")
This is what importmap-rails does, among other things. In case you want to relocate anything back to app/assets.
Here is a short overview of who lives where:
app/
├─ assets/ # used by sprockets-rails, everything else hooks into it
│ ├─ build/ # compiled assets (jsbundling-rails, cssbundling-rails, tailwindcss-rails)
│ ├─ config/ # precompile `build/` if any of these three ^ are used
│ │ # or precompile `app/javascript/` if importmap-rails is used
│ ├─ stylesheets/ # used by cssbundling-rails, tailwindcss-rails
│ └─ javascripts/ # not used in rails 7, but any directory can be added to `assets/`,
│ # just add it to precompilation manifest as well https://stackoverflow.com/q/72305291/207090
└─ javascript/ # used by jsbundling-rails, importmap-rails and anything node related.
└─ controllers/ # used by stimulus-rails
Also, rails gems themselves use app/assets/javascripts to ship any js files.
I have the following folder structure:
app
├── assets
├── controllers
├── helpers
├── mailers
├── market_adapters
│ └── german.rb
│...
And the file market_adapters/german.rb is:
module MarketAdapters #(I've also tried naming it singular)
class German
end
end
When running tests I get the error:
/gems/activesupport-5.0.0/lib/active_support/dependencies.rb:512:in
`load_missing_constant': Unable to autoload constant German,
expected .../app/market_adapters/german.rb to define it (LoadError)
Adding the market_adapters folder to the autoload_paths seems to have no effect config.autoload_paths << "#{Rails.root}/app/market_adapters"
If I move the market_adapters to the lib folder, everything works. But still would like to have it under app, any ideas?
By the way, I'm using Rails 5.
All the subfolders in app are automatically auto-loaded and added to the load path. Therefore, the folder market_adapters is added to the load path, and the file called german.rb is expected to define the German class.
If you really want to use market_adapters as namespace and keep the file in app, you need to store it in the folder app/market_adapters/market_adapters/german.rb.
The right place, however, is in lib.
I'm working on integrating a javascript library into the rails asset pipe line.
The javascript expects a fonts/ and images/ folder to be available at the root level, but I think Rails is precompiling these to assets/fonts/ and assets/images.
The reason I think this is the case is because if I put the fonts and images folder directly into the public folder everything works.
But if I place fonts and images in the apps/assets/fonts and apps/assets/images the javascript returns 404 errors for the requested fonts and images.
Is there somewhere in Rails config that I can tell Rails to precompile these fonts and images folders to public/ instead of public/assets/?
You should use the asset pipeline helpers in your case, especially because of the fingerprinting strings that will be appended to the name of the assets.
to do that:
1.change the references to the font/image files to
using the asset helper
<%= asset_path 'fontFileNameAndExtension' %>
using asset image helper
<%= image_path 'imageFileNameAndExtension' %>
2.change the extension of your .js file to .js.erb
3.include the name of your js file into application.js as
//= require YourJsFileName
4.execute the pre-compile again, and you might want to clean the compiled assets first:
rake assets:clobber
rake assets:precompile
The title pretty much says it all...
I tried adding /app/assets/fonts/font.woff and referencing it from my css file with /app/assets/fonts/font.woff but it doesn't seem to work.
Any ideas?
It turns out that the asset pipeline that #JimLim mentioned works a bit differently in Rails 4. Full docs here, but here's the relevant excerpt:
2 How to Use the Asset Pipeline
In previous versions of Rails, all
assets were located in subdirectories of public such as images,
javascripts and stylesheets. With the asset pipeline, the preferred
location for these assets is now the app/assets directory. Files in
this directory are served by the Sprockets middleware.
Assets can still be placed in the public hierarchy. Any assets under
public will be served as static files by the application or web
server. You should use app/assets for files that must undergo some
pre-processing before they are served.
In production, Rails precompiles these files to public/assets by
default. The precompiled copies are then served as static assets by
the web server. The files in app/assets are never served directly in
production.
So I ended up moving my /fonts directory into /public adjusting my paths in the #font-face declaration accordingly and everything works fine.
You have to tell Rails to include your fonts directory in the asset pipeline, as follows:
config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
Finally, let Rails figure out the correct path for you, so you don't have to mess with the prefix app, app/assets etc. Add a .erb extension to your css/scss file e.g. application.css.erb, and use embedded ruby:
src: url("<%= asset_path('fonts.woff') %>");
(Related question)
Can anyone explain what the use of the following directories is?
app/assets/
lib/assets/
vendor/assets/
These directories are all a part of Rails' Asset Pipeline.
Conceptually, the app/assets directory is for your application assets (for instance, the stylesheets and images for your application). lib/assets is for all of the code that you've written that stands alone from your rails app (javascript library, maybe). vendor/assets is meant to house all third party libraries (e.g. jQuery).
All of these paths are included by default in the asset pipeline. This means that their contents can be included into other files using sprockets, concatenating automatically into one file (javascript or css), reducing the number of requests and thus the loading time. The asset pipeline can also compile your coffeescript and minify your javascript for production.