How can I peek at intermediary files processed by asset pipeline? - ruby-on-rails

I've got somefile.js.coffee.erb file which is processed by Rails asset pipeline. My ERB code returns some string that cannot be parsed by Coffee which result in SyntaxError exception. I would like to peek into generated somefile.js.coffee file, or in general any intermediary file processed by asset pipeline.
I've tried to examine Sprockets with no luck:
environment = Sprockets::Environment.new
MyApplication::Application.config.assets.paths.each {|p| environment.append_path p}
rerb = environment['somefile.js.coffee.erb']
rerb.source #=> it's already preprocessed
Or to look into \tmp\cache\assets but there are also only preprocessed files, additionaly obscured by fingerprinted name.
Maybe there is a way to hook into asset-pipeline I have no idea how..
Why I need ERB? To generate client-side-model stubs with fields and validations matching Rails model using KnockoutJS (https://github.com/dnagir/knockout-rails extended -> https://github.com/KrzysztofMadejski/knockout-rails).
I am using Rails '~> 3.2.12', sprockets (2.2.2).
Edit: I've ended up injecting erb code in ### comments, to sneak-peak at generated code while coffeescript file is still compiling:
###
<%= somefun() %>
###
Altough I would suggest using #Semyon Perepelitsa answer as it produces coffee script file as it is seen by coffee compiler.

Just remove "coffee" from the file extension temporarily: somefile.js.erb. You will see its intermediate state at /assets/somefile.js as it won't be processed by CoffeeScript.

I wonder if you can put <% binding.pry %> just before the line and mess around till you get it right. Never tried during a compile and don't use coffeescript. In theory, it should work (or is worth a shot) so long as you put gem pry in your Gemfile and run bundle first.

Related

Print the names of all assets in the Asset Pipeline?

I'm trying to debug why some assets are found and others not in the Asset Pipeline. i've tried a lot of obvious things (like typos, clearing tmp, clean/clobber).
Now I placed binding.pry right before where the image path is generated, and I'd like to view (print to the rails console / debugger) the name of every asset rails thinks is available.
How can I do that?
You can take a look at the manifest:
Rails.application.assets_manifest
# or just the files
# this is empty in some of my apps, no idea why, maybe cache or some
# lazy loading that I'm missing:
Rails.application.assets_manifest.assets
Or maybe loop through asset paths:
Rails.configuration.assets.paths.flat_map{ |path| Dir.glob("#{path}/*.{js,css}") }
Please note, this doesn't answer the question (how to view the available assets in the console/debugger), and therefore shall not be accepted as an answer, but it's a small start: showing how to view assets from the terminal:
rails webpacker:clean
rails webpacker:clobber
rails webpacker:compile
The last step will print all the available assets to the terminal.
Another way is to run bin/webpack from the terminal, and in the output will be each asset. Again, this doesn't provide the list from the console or debugger.

How to make Rails render slim templates instead of erb templates?

In my current project I used to use erb as the default view template, then I decided to switch to slim, so I used tools to convert all the .erb files to .slim files.
Now I have erb and slim files co-exist in the same folder, the problem is after I restarted the rails server, it still rendered the old .erb files, not the .slim files as I expected.
I have already put 'gem slim-rails' in my Gemfile and updated it, so what else should I do to let Rails choose these slim templates to render instead of the erb templates?
PS: Do I have to delete all the .erb files? Because I want to keep them as a study purpose.
i think you can just change the name of the files which contain those erb templates, so no need to delete them. So when you want to use erb, change to original name.
Make this configuration in config/application.rb
class Application < Rails::Application
...............................
config.generators do |g|
g.template_engine :slim
end
end
It seems that the answer to my last question is YES, I have to delete all the .erb templates, only in this way can Rails render the .slim templates as expected.
Though I still don't know why Rails prefer erb than slim when they both exist, could it be that e in erb priors to s in slim?

Always preprocess a specific Javascript file with Rail 3.1 asset pipeline

Is there a way to always run the ERB preprocessor on a Javascript file?
I'm using Mustache to use the same templates on the client and server. I'd like to include these templates in my application.js files so they're available on the client. So I'm preprocessing my Javascript file (templates.js.erb, which then gets required in application.js) with erb:
App.templates.productShow = <%= MustacheController.read("product/show").to_json %>;
This works great but when I edit the "product/show.html.mustache" template I need to also edit "templates.js.erb" so Rails knows to recompile this file which then picks up the latest changes from the mustache template.
There's no issue running this in production since the assets get compiled when I deploy, but it's annoying when developing. Ideally I could set the preprocessor to run on "templates.js.erb" every time I reload. My current solution is to inline the Javascript in the application layout but it would be nice to keep it separate.
I ended up writing a guardfile for this that adds a timestamp to the end of the file. Just touching the file is enough for sprockets to recompile but if you're using git you need to actually alter the file. Otherwise anyone else who pulls in the code won't get the latest preprocessed files. Here's the code...
#!/usr/bin/ruby
guard 'mustache' do
watch(%r{app/templates/.+\.mustache})
end
require 'guard/guard'
module ::Guard
class Mustache < ::Guard::Guard
def run_on_change(paths)
# file to be updated when any mustache template is updated
file_name = "./app/assets/javascripts/templates.js.erb"
# get array of lines in file
lines = File.readlines(file_name)
# if last line is a comment delete
lines.delete_at(-1) if lines[-1].match /\/\//
# add timestamp
lines << "// #{Time.now}"
# rewrite file
File.open(file_name, "w") do |f|
lines.each{|line| f.puts(line)}
end
end
end
end
This seems to be a common complaint with the pipeline - that you have to touch a file that references variables for those changes to be reflected in development mode. A few people have asked similar questions, and I do not think there is a way around it.
Forcing Sprockets to recompile for every single request is not really a viable solution because it takes so long to do the compilation.
Maybe you could set up guard to watch your mustache directory and recompile templates.js.erb when you make changes to it. Similar to how guard-bundler watches your Gemfile and rebundles on change.

Most appropriate way to generate directory of files from directory of template files with Rails and ERB?

My goal is to generate a directory of static html, javascript, and image files within my Rails (3) app, driven by ERB templates. For example, as a developer I might want to generate/update these files:
#{Rails.root}/public/products/baseball.html
#{Rails.root}/public/products/football.js
..from the following template files:
#{Rails.root}/product_templates/baseball.html.erb
#{Rails.root}/product_templates/football.js.erb
Ideally the templates would have access to my app's Rails environment (including URL helpers, view helpers, partials, etc.).
What's the latest and greatest way to accomplish this?
I experimented with a custom Rails generator, but found that I needed to write custom logic for skipping non-ERB files, substituting file names, etc. There must be a better way.
I'm not sure what you are trying to do exactly, that may help provide better answers, but here is some useful information:
You can call into erb directly, some information on that is here, which have probably already been doing:
http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html
For the list of template files an easy Dir.glob should be able to help find the specific files easily and loop through them:
http://ruby-doc.org/core/classes/Dir.html#M000629
The tricky part I wouldn't know how to advise you on is getting access to the helpers and other things Rails provides. The helpers that you write are just modules, so you could mix those in, something similar might be possible with the built-in rails helpers.
This is interesting and related but doesn't directly answer your question, since its uses the Liquid templating engine instead of ERB, but otherwise, it does some of the static site generation you are talking about:
https://github.com/mojombo/jekyll
This is how I accomplished something similar. It accepts source and destination directories, wipes out the destination, then processes the source directory, either ERB-processing files and placing them in the destination or simply copying them (in the case of on-ERB files). It would need to be modified to handle recursively processing a directory.
I invoke it from a rake task like so:
DirectoryGenerator.new.generate(Rails.root.join('src'), Rails.root.join('public', 'dest'))
class DirectoryGenerator
include Rails.application.routes.url_helpers
include ActionView::Helpers::TagHelper
default_url_options[:host] = 'www.example.com'
def generate(source, destination)
FileUtils.rmtree(destination)
FileUtils.mkdir_p(destination)
Dir.glob(File.join(source, '*')).each do |path|
pathname = Pathname.new(path)
if pathname.extname == '.erb'
File.open(destination.join(pathname.basename.sub(/\.erb$/, '')), 'w') do |file|
file.puts(ERB.new(File.read(path)).result(binding))
end
else
FileUtils.cp(pathname, File.join(destination, pathname.basename))
end
end
end
end
Have you looked into Rails templates?
http://m.onkey.org/rails-templates for instance..
Not sure what you are getting at exactly.. are you trying to generate client sites by providing a few parameters.. that the end goal?

Is there any gem can dump the data from and to yml files?

I'm find such a gem a whole day, but not find a good one. I want to write one, but I'm not able to do it.
The data in my database may be English text, which will be dump to a yml file with plain text. And some are non-English text, which will be binary type.
And both of them may have such code:
<% xxx %>
When I use rake db:fixtures:load to load them into database, error may occur: method xxx not found.
I wan't to find a good gem can handle this problem. Thank for any help
UPDATE
I have gave up finding such a gem. At first, I think it's a easy task, but now, after some researchings, I have to say, it's much harder than I expected.
The reason you are having problems is because the Fixture loader will pass your fixture through erb before loading the data. This means that if you have <% xxx %> in your yaml file then Rails will see that as erb and try to run a method called xxx.
There does not seem to be an easy way to turn off erb processing of fixtures. I have tried replacing the fixtures with CSV fixtures and this still does ERB pre-processing.
Without a simple answer I have to ask the question Why do you have these strings in your file?
Do you want them to be expanded by erb?
Err...I'm not sure if you actually need a gem for this? Rails natively can turn any model into YAML.
Let's say you have a model called "Objects". You could hit a route that looks like:
/objects.yaml
and you would get a giant text file of all your Objects in YAML form.
Of course, you would want to have something like:
respond_to do |format|
format.yaml {render :yaml => #objects}
end
in your restful controller.
If you'd rather not hit a route to do this, you can always do
#yaml = []
#objects.each do |object|
#yaml.push object.to_yaml
end
anywhere in ruby, which will give you an array of yaml objects, that you can then write to a file at your leisure.
I imagine that if rails itself is generating the yaml, then it would be able to then later load it as a fixture?

Resources