danengle
danengle

Reputation: 566

Accessing the app name from inside a rails template when generating rails app

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

Upvotes: 8

Views: 6248

Answers (9)

David Hempy
David Hempy

Reputation: 6237

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: (Prior to Rails 7)

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"

And in Rails 7 and beyond: (Thanks to @linkOff )

rails(development)> Rails.application.class.module_parent
=> Fizzbuzz
rails(development)> Rails.application.class.module_parent.to_s
=> "Fizzbuzz"

Upvotes: 1

danengle
danengle

Reputation: 566

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.

Upvotes: 8

mriddle89
mriddle89

Reputation: 162

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

Upvotes: 5

Straff
Straff

Reputation: 5749

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.

Upvotes: 0

Daniel Kehoe
Daniel Kehoe

Reputation: 10952

In Rails 3, use the app_name attribute.

See the documentation for the Rails::Generators::AppGenerator.

Upvotes: 6

Mike Fischer
Mike Fischer

Reputation: 1083

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

Upvotes: 17

RonanOD
RonanOD

Reputation: 885

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.

Upvotes: 0

Abie
Abie

Reputation: 10835

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.

Upvotes: 1

Mike Woodhouse
Mike Woodhouse

Reputation: 52316

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?

Upvotes: 4

Related Questions