I am using Ruby on Rails 3.0.7 and I am writing some documentation for my application using RDoc. Since I have not found on the Web some good documentation with examples, what I would like to know is how to use the :include: directive at all.
Can you make me an example of using that in application files?
Here is the doc: http://rdoc.rubyforge.org/RDoc/Markup.html
And here is a very basic example:
First a ruby file, say /tests/my_func.rb
#:include: doc.txt
def my_function
puts "yo"
end
Then a doc /tests/documentations/doc.txt
This describes the method very well
In command line (executed from /tests):
rdoc -i /Users/benjaminroth/Sites/Tests/rdoc/descriptions
AIUI, :include: allows you to (surprise) include the contents of another file, keeping the same indentation level of the block in which the include appears.
It will look for the named file in the current directory, but it's something you can override by means of the --include switch.
If you want an example, this could prove useful.
Related
In a Ruby on Rails application, where would the most logical place be to put a "file flag."
I am attempting to externalize configuration and allow the presence of a file to be the deciding factor on whether or not something shows on the webapp.
Right now, I have a file here:
lib/
deployment_enabled
Model deployment.rb
class Deployment...
...
def deployment_enabled?
Dir["#{Rails.root}/lib/deployment_enabled"].any?
end
end
Now this works of course, but i'm not sure this follows the MVC paradigms, since the lib directory should consist of scripts. I could put it in config, but again - not sure it belongs there as rails uses this for rails specific configuration, not necessarily the webapp.
I could of course put this in our database, but that require a new table to be created, and that seems unnecessary.
Where's the most logical place to put this flag file? Does Rails have a directory that's created during the generation to put these sort of files?
I suggest using the Rails tmp directory for this purpose. Then:
File.exist?("#{Rails.root}/tmp/deployment_enabled")
Phusion Passenger use this kind of mechanism too.
https://www.phusionpassenger.com/library/walkthroughs/basics/ruby/reloading_code.html#tmp-always_restart-txt
I recommend that you follow the Twelve-Factor App guidelines and keep your code separate from your configuration. In this case you are really talking about a simple boolean value, and the presence of the file is just the mechanism you use to define the value. This should be done instead through an environment variable.
Something like:
DEPLOYMENT_ENABLED=1 RAILS_ENV=production rails server
You would then use an initializer in Rails to detect the value:
# config/initializers/deployment.rb
foo if ENV['DEPLOYMENT_ENABLED']
The value can still be modified at runtime, e.g., ENV['DEPLOYMENT_ENABLED'] = 0.
I would like to override some of the methods defined in the file document_presenter.rb. How can I do this? This module is defined inside the Blacklight gem's "lib" directory.
Is there an easy way to do this? I'm fairly new to Ruby and Rails (coming from a pure Java background), so this is kind of difficult.
Thanks.
It sounds like you are talking about monkey patching the methods in the Backlight gem. You might want to read this post that explains more about monkey patching - and how not to break things badly!
In Ruby, you can always open an existing class, with the class keyword, and use the def keyword to redefine the original method.
class DocumentPresenter
def method_you_want_to_override
# Your code here.
end
end
So for example, you could put the above code into your lib folder:
lib/document_presenter.rb
See this answer re: auto-loading files in the lib folder.
After you've done that, whenever you call the method you've monkey patched on an instance of the DocumentPresenter class, the Ruby interpreter will run your code instead.
This is not recommended, as it can have dangerous and unpredictable results, as per then blog post I linked to.
A better practice, in Ruby 2, is to use Refinements.
In the Rails docs there seem to be different default locations for I18N strings, depending if the I18N-lookup was initiated from a view, model / validation, controller, helper, ..., if it's a label, etc...
How can I see where Rails is trying to lookup things by default, e.g. when I just use t('.something') ?
You can monkey patch the I18N backend in development mode to print out the I18n keys that are looked up in the backend.
Check here:
http://www.unixgods.org/Rails/where_is_Rails_trying_to_lookup_L10N_strings.html
the standalone I18n.t does not prefix your translation key in any way, here are the helper methods/modules that are responsible for the rails' magic:
(click on the "source" link below the methods' description to see what's happening inside)
ActionView:
http://api.rubyonrails.org/classes/ActionView/Helpers/TranslationHelper.html#method-i-t
scope_key_by_partial
ActiveModel:
http://api.rubyonrails.org/classes/ActiveModel/Translation.html#method-i-i18n_scope
AbstractController
http://api.rubyonrails.org/classes/AbstractController/Translation.html
The solution above does not help find what file a key is being looked up in. I did not find any elegant solution to this, below is the best method I came up with. The instructions would have to be adapted for a production box.
Open up a rails console bundle exec rails c
Run I18n.load_path.join("\n") and copy this to your clipboard. If you use pry with some clipboard helpers, just run copy in the console
Open up a new terminal window and run pbpaste | ack 'en.yml$' | xargs ack 'key:' This will print out a list of files containing the key I18n is trying to access
In rails 3.2 (maybe also lower versions), a span is produced by the t - helper in views that shows you which key was searched for the translation. This isn't a solution for all cases (from controller and so on), but I think it can be the answer for a lot of people who search for this question, where the full monkey patch from above would be over the top (the monkey patch also works for me in i18n 0.7.0 and gives more detail)
title="translation missing: de.<path to key>"
If the translation you're trying to debug is being set in the controller, there is a simple solution:
Set a variable in the controller to a tag that's doesn't exist and read the path return by the translation missing warning.
For instance in the controller
#test = t('.choco_pizza')
In your view:
<%= #test %>
Will return:
translation missing: fr.unexpected_namespace.controller_name.action_name.choco_pizza
I'm messing around with rails 2.3 templates and want to be able to use the app name as a variable inside my template, so when I use...
rails appname -m path/to/template.rb
...I want to be able to access appname inside template.rb. Anyone know how to do this?
Thanks
I was looking for an answer to this question. unfortunately the answer above (#root) doesn't seem to work in Rails 3.
Here's the variables you can access in Rails 3 app templates (even easier):
#app_name
#app_path
Thanks for the answers. Mike Woodhouse, you were so close. Turns out, all you need to do to access the appname from inside your rails template is...
#root.split('/').last
The #root variable is the first thing created when initializing templates and is available inside your rails templates. RAILS_ROOT does not work.
In Rails 3, use the app_name attribute.
See the documentation for the Rails::Generators::AppGenerator.
I ran into a similar problem, none of the variables listed above were available to me in Rails 4. I found that #name was available while running
rails plugin new engines/dummy -m my_template.rb
There are other useful variables available from within the template. You can see for yourself and play around by utilizing pry. Inside my template I added
require 'pry'; binding.pry
and then ran ls to show a list of available instance variables
ls -i
instance variables:
#_initializer #app_path #behavior #destination_stack #extra_entries #name #output_buffer #shell
#_invocations #args #builder #dummy_path #gem_filter #options #rails_template #source_paths
#after_bundle_callbacks #author #camelized #email #in_group #original_name #shebang
There's probably a more straightforward way, but this seems to work:
RAILS_ROOT.split('/').last
EDIT: Bleah - this got voted down once, and the voter was right. If I'd read the question more carefully, I'd have noticed the 2.3 and template.rb elements. Apologies.
I suspect that RAILS_ROOT won't have been created at the point that you need the app name. Looking at ruby\lib\ruby\gems\1.8\gems\rails-2.2.2\bin\rails, however, almost the first thing that happens is this:
app_path = ARGV.first
It's used at the end of the script to allow a chdir and freeze to be done if needed - I didn't know I could insta-freeze at creation, so I learned something new at least. ARGV then gets used here:
Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app')
which quickly gets us to the place where ARGV is really handled:
rails-2.3.1\lib\rails_generator\scripts.rb
where I see
Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke!
Somewhere below here is probably where the templating gets handled. I'm afraid I'm at a very early stage with 2.3 and templating is an area that I haven't looked at yet.
Does that help any better than my first effort?
RAILS_ROOT will give you the absolute path to your root directory. Your app name will be the portion of the string after the final '/' which you can grab in any number of ways.
EDIT: Not quite enough to get the job done. Mike and Dan iron it out below.
I believe the preferred way now is to call Rails.root and no longer RAILS_ROOT. Apparently someone on planet rails has an aversion to uppercase or some similar important reason. As of 2.3.5 they both appear to work.
I was getting error
`template': undefined local variable or method `app_name'
ruby 1.9.2p290, rails 3.2.11, thor 0.18.0, Windows
but with rails 2.3 generator:
class DynanavGenerator < Rails::Generators::Base
(can't be sure whether this error happened under rails 3.0.9 or earlier)
changed class definition to be:
class DynanavGenerator < Rails::Generators::NamedBase
which then gave:
No value provided for required arguments 'name'
I then added a 'name' ("something" below):
rails generate dynanav something --force
which gave the original error, so I then added:
def app_name
#name.titleize
end
to the class and all was well.
As of Rails 4 (maybe earlier versions?), use Rails.application.class to get the application name. For example, if your app is named Fizzbuzz, here are a few ways you might access it:
rails(development)> Rails.application.class
=> Fizzbuzz::Application
rails(development)> Rails.application.class.name
=> "Fizzbuzz::Application"
rails(development)> Rails.application.class.parent
=> Fizzbuzz
rails(development)> Rails.application.class.parent.to_s
=> "Fizzbuzz"
I'm currently working on a largish Ruby on Rails project. It's old enough and big enough that it's not clear if all views are actually in use.
Is there any script/plugin out there that can generate a list of unused view files?
Take a look at the following script on GitHub http://github.com/vinibaggio/discover-unused-partials
I wrote a script to find unused partials/views. I assumed, though, that "unused" means that a view-file is present for which no controller-method is defined (any more). The script does not check whether the view is called because there is no link from the default-route to it. This would have been far more complex.
Place the following script in the application's script folder:
#!/usr/bin/env ruby
require 'config/environment'
(Dir['app/controllers/*.rb'] - ['app/controllers/application.rb']).each do |c|
require c
base = File.basename(c, '.rb')
views = Hash.new
Dir["app/views/#{base.split('_')[0]}/*"].each do |v|
views.store(File.basename(v).split('.')[0], v)
end
unused_views = views.keys - Object.const_get(base.camelcase).public_instance_methods - ApplicationController.public_instance_methods
puts "Unused views for #{base.camelcase}:" if unused_views.size > 0
unused_views.each { |v| puts views[v] }
end
It is kinda hackish and unfinished, but it does the job - at least for me.
Execute it like this (you only need to change the execute-bit the first time with chmod):
chmod +x script/script_name
./script/script_name
Enjoy!
Just install and run the discover-unused-partials gem:
gem install discover-unused-partials
discover-unused-partials rails_root_directory
Iterate through your partials, grep (or awk) the project for the name of the file. Adjust your search regex to look for "render :partial" at beginning of line for generic partials (eg, "_form").