ruby on rails - present - Canalización de activos de Rails 3.1: ¿cómo cargar scripts específicos del controlador?
the asset is not present in the asset pipeline (7)
Me gusta la solución de albandiguer . Con lo cual he encontrado que los activos javascript / coffeescript no se precompilan individualmente. Lo cual causa todo tipo de errores al intentar usar javascript_path
. Compartiré mi solución a ese problema después de abordar un problema que algunas personas mencionaron en sus comentarios. Se trata principalmente de un conjunto parcial de controladores llamados archivos JavaScript.
Así que construí una aplicación auxiliar para detectar si el archivo existe en el directorio javascript independientemente de la extensión .coffee / .js:
module ApplicationHelper
def javascript_asset_path(basename)
Sprockets::Rails::Helper.assets.paths.select{|i|
i =~ /javascript/ and i =~ /#{Rails.root}/
}.each do |directory|
if Dir.entries(directory).map {|i| i.split(''.'')[0]}.compact.
include? basename
return File.join(directory, basename)
end
end
nil
end
end
Este método devolverá la ruta completa al archivo javascript si existe. De lo contrario, devuelve nil. Entonces, siguiendo el comentario de Pencilcheck puedes agregar este método para incluir condicional:
<%= javascript_include_tag(controller_name) if javascript_asset_path(controller_name) %>
Y ahora tienes una inclusión condicional adecuada. Ahora para el tema de los activos precompilados. En general, para la optimización no desea que los activos se precompilen individualmente. Sin embargo, puede hacerlo si debe:
# Live Compilation
config.assets.compile = true
Puede agregar esto haga su archivo de configuración de entorno. Pruébelo primero en su archivo de entorno de desarrollo. De nuevo, esto es desaconsejable. La cartera de activos de Rails usa Piñones para optimizar todo:
Sprockets carga los archivos especificados, los procesa si es necesario, los concatena en un único archivo y luego los comprime (si Rails.application.config.assets.compress es verdadero). Al servir un archivo en lugar de muchos, el tiempo de carga de las páginas se puede reducir considerablemente debido a que el navegador realiza menos solicitudes. La compresión también reduce el tamaño del archivo, lo que permite que el navegador los descargue más rápido.
LEA LA DOCUMENTACIÓN PARA OBTENER MÁS INFORMACIÓN SOBRE LA MECÁNICA DE Sprockets (Asset Pipeline) http://guides.rubyonrails.org/asset_pipeline.html
Los activos no son precompilados individualmente. Por ejemplo, cuando intento:
<%= javascript_include_tag ''event'' %>
Yo obtengo:
Sprockets :: Rails :: Helper :: AssetFilteredError: filtrado de activos y no se servirá: agregue
Rails.application.config.assets.precompile += %w( event.js )
aconfig/initializers/assets.rb
y reinicie su servidor
Entonces puede incluir qué activos se precompilarán individualmente. Solo necesitamos agregar el controlador relevante llamado javascript en nuestro inicializador de activos. Bueno, podemos hacer esto programáticamente.
Para obtener una lista de nombres de controladores, usaré el ejemplo de ecoologic :
all_controllers = Dir[
Rails.root.join(''app/controllers/*_controller.rb'')
].map { |path|
path.match(/(/w+)_controller.rb/); $1
}.compact
Y ahora para obtener el nombre de todos los archivos javascript que coincidan con el nombre base del nombre del controlador, puede usar lo siguiente:
javascripts_of_controllers = Sprockets::Rails::Helper.assets.paths.select{|a_path|
a_path =~ /javascript/ and a_path =~ /#{Rails.root}/
}.map {|a_path|
Dir.entries(a_path)
}.flatten.delete_if {|the_file|
!the_file[''.js'']
}.collect {|the_file|
the_file if all_controllers.any? {|a_controller| the_file[a_controller]}
}
Entonces puedes intentar:
# config/initializers/assets.rb
Rails.application.config.assets.precompile += javascripts_of_controllers
Esto le dará una lista de todos los archivos javascript, sin ruta de directorio, que coincidan con su nombre de controlador. Tenga en cuenta que si el nombre de su controlador es plural, el nombre de javascript debería serlo también. También tenga en cuenta que si el controlador es singular y el archivo javascript es plural, aún así lo incluirá debido a que the_file[a_controller]
tendrá éxito en una coincidencia parcial.
No dude en probar esto en su configuración de Rails.application.config.assets.precompile
. Sé que esto te da la lista de archivos correctamente. Pero te dejo para probarlo. Avíseme si hay algún matiz relacionado con la precompilación de esta manera, porque tengo curiosidad.
Para obtener una explicación muy detallada sobre cómo precompilar los activos, consulte este blog: http://www.sitepoint.com/asset-precompile-works-part/
Si genero un nuevo controlador en Rails 3.1, también se agregará automáticamente un archivo javascript con el nombre del controlador. En primer lugar, pensé que este archivo javascript se usará solo cuando se llame al controlador relacionado.
Por defecto está la instrucción //= require_tree .
en el archivo application.js
, que incluye todos los archivos javascript en su árbol.
¿Cómo podría cargar solo el script específico del controlador?
Otra opción es usar la gema pluggable_js .
Para cargar solo el archivo necesario name_of_the_js_file.js:
eliminar el
//=require_tree
deapplication.js
conserve su archivo js (que desea cargar cuando se carga una página específica) en la cartera de activos
agregar un ayudante en
application_helper.rb
def javascript(*files) content_for(:head) { javascript_include_tag(*files) } end
ceder a su diseño:
<%= yield(:head) %>
agregue esto en su archivo de vista:
<% javascript ''name_of_the_js_file'' %>
Entonces debería estar bien
Recientemente encontré un enfoque simple para usar scripts generados para un controlador específico. Yo uso para esa solución gem gon . Agregar en un controlador:
class HomesController < ApplicationController
before_filter :remember_controller
private
def remember_controller
gon.controller = params[:controller]
end
end
Después de eso abre tus homes.js.cofee
y agrega al principio del archivo:
jQuery ->
if gon.controller == "sermons"
# Place all functions here...
Eso es todo.
Siempre incluyo esto dentro de mis archivos de diseño. Puede extender tu js a la acción
<%= javascript_include_tag params[:controller] if AppName::Application.assets.find_asset("#{params[:controller]}.js") %>
<%= javascript_include_tag "#{params[:controller]}_#{params[:action]}" if AppName::Application.assets.find_asset("#{params[:controller]}_#{params[:action]}.js") %>
Su problema puede resolverse de diferentes maneras.
Agregue los activos dinámicamente
Tenga en cuenta que esta no es una buena solución para el modo de producción, ¡ya que las especificaciones de su controlador no se precompilarán!
Agregue a nuestro asistente de aplicación el siguiente método:
module ApplicationHelper def include_related_asset(asset) # v-----{Change this} if !YourApp::Application.assets.find_asset(asset).nil? case asset.split(''.'')[-1] when ''js'' javascript_include_tag asset when ''css'' stylesheet_link_tag asset end end end end
Llame al método de ayuda en su archivo de
layout
:<%= include_related_asset(params[:controller].to_param + ''_'' + params[:action].to_param . ''js'') %>
Cree activos específicos para sus acciones de controlador. P.ej.
controller_action.js
No olvide cambiar YourApp
por el nombre de su aplicación.
Usa el yield
- Agregue
<%= yield :head%>
a su cabezal de diseño Incluya sus activos de sus vistas de acción:
<% content_for :head do %> <%= javascript_include_tag ''controller_action'' %> <% end %>
Consulte las guías de Rails para obtener más información.
Una solución elegante para esto es requerir controller_name en su javascript_include_tag
ver http://apidock.com/rails/ActionController/Metal/controller_name/class
<%= javascript_include_tag "application", controller_name %>
controller_name.js se cargará y también se encuentra en el activo, por lo que puede requerir otros archivos desde aquí.
Ejemplo, el índice de carros # index dará
<%= javascript_include_tag "application", "cars" %>
donde cars.js puede contener
//= require wheel
//= require tyre
¡Disfruta!