One controller rendering using another controller&

2019-01-22 11:38发布

问题:

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

回答1:

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' %> 


回答2:

You can achieve it with:

render 'question/answer'


回答3:

You could try the inherit_views plugin (http://github.com/ianwhite/inherit_views/tree/master) I mentioned here in the answer to this question.



回答4:

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 < QuestionController
  def self.local_prefixes
    super + ['question']
  end
end
AnotherQuestionController._prefixes
# => ["another_question", "question", "application"]