Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One controller rendering using another controller's views

I have QuestionController I now have AnotherQuestionController with actions which should render using templates and partials in app/views/question/ Is this possible? Seems like it should be.

I've tried

render :template => "question/answer"

but answer.html.erb includes partials and I get errors like

"Missing template another_question/_my_partial.erb in view path"

So is there a way to tell Rails "treat AnotherQuestionController as if its QuestionController and look for views and partials in app/views/question"? Or will I have to create app/views/another_question - which will cause duplication (this can't be the Rails way).

Thanks

like image 484
Paul Avatar asked Jun 18 '09 14:06

Paul


3 Answers

Template rendering should actually work

 render :template => "question/answer"

The problem you were having is from the partials looking in the wrong place. The fix is simple, just make your partials absolute in any shared templates. For example, question/answer.html.erb should have

<%= render :partial => 'question/some_partial' %>

rather than the usual

<%= render :partial => 'some_partial' %> 
like image 159
Ben Hughes Avatar answered Sep 19 '22 23:09

Ben Hughes


You can achieve it with:

render 'question/answer'
like image 32
klew Avatar answered Sep 21 '22 23:09

klew


Rails uses a list of prefixes to resolve templates and partials. While you can explicitly specify a prefix ("question/answer"), as suggested in another answer, this approach will fail if the template itself includes unqualified references to other partials.

Assuming that you have an ApplicationController superclass, and QuestionController inherits from it, then the places Rails would look for templates are, in order, "app/views/question/" and "app/views/application/". (Actually it will also look in a series of view paths, too, but I'm glossing over that for simplicity's sake.)

Given the following:

class QuestionController < ApplicationController
end

class AnotherQuestionController < ApplicationController
end

QuestionController._prefixes
# => ["question", "application"]
AnotherQuestionController._prefixes
# => ["another_question", "application"]

Solution #1. Place the partial under "app/views/application/" instead of "app/views/question/", where it will be available to both controllers.

Solution #2. Inherit from QuestionController, if appropriate.

class AnotherQuestionController < QuestionController
end
=> nil
AnotherQuestionController._prefixes
# => ["another_question", "question", "application"]

Solution #3. Define the class method AnotherQuestionController::local_prefixes

This was added in Rails 4.2.

class AnotherQuestionController < ApplicationController
  def self.local_prefixes
    super + ['question']
  end
end
AnotherQuestionController._prefixes
# => ["another_question", "question", "application"]
like image 1
Steve Avatar answered Sep 19 '22 23:09

Steve