Question

I am doing the Lynda.com rails tutorial and they explain how to render another view than the default one using render('methodname').

However, I noticed this rendering is not "nested". For example, in the code below, localhost:3000/demo/index would generate the view in views/demo/hello.html.erb, while localhost:3000/demo/hello would render the text 'Hello there'.

Is there a way to have "nested" rendering, i.e. such that requesting demo/index would return 'Hello there' in this example?

(Also, some use cases for nested rendering would be nice. I am asking only out of curiosity.)

class DemoController < ApplicationController
  def index
     render ('hello')            
  end

  def hello
    render(:text => 'Hello there')
  end

end
Was it helpful?

Solution

I don't know what you exactly mean by nested rendering.

Scenario #1

If you want action "index" to be triggered but template "hello.html.erb" to be shown, you can do

def index
  render :action => :hello
end

This will render the template app/views/demos/hello.html.erb (or other format if you want it to (i.e. specify it in the url)).

So render :action => :hello is just a shortcut.

You can also do render :template => "hello.html.erb" or render :file => Rails.root.join("app/views/demos/hello.html.erb") (sometimes useful).

Scenario #2

If you want to render that text, you can just call hello method inside index method

def index
  hello
end

If you don't want other stuff from hello action to be run you can separate it to other method, like so:

def render_hello
  render :text => "Hello world"
end

def index
  # some other stuff going on...
  render_hello
end

def hello
  # some other stuff going on...
  render_hello
end

You can not render twice in the same action.

Btw the url should not say /demos/index but just /demos. Index is the default action for resources route (resources :demos).

Please select the scenario which suits you (so I can remove unnecessary text from this answer).

OTHER TIPS

You're currently trying to render in a controller, all rendering should be handled in the views in Rails.

So for your structure above, your DemoController should be located in a file at

app/controllers/demo_controller.rb

and the views that will be rendered will be in files located at:

app/views/demo/index.html.erb

and

app/views/demo/_hello.html.erb (The leading underscore on the file name _hello.html.erb indicates to Rails that this is a "partial" to be rendered inside another page)

Inside the index.html.erb file you would call a render to the hello.html.erb file. Your resulting code should look like this:

demo_controller.rb

class DemoController < ApplicationController

  def index          
  end

end

index.html.erb

<%= render 'demo/hello' %>

_hello.html.erb

<p>Hello there</p>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top