16

I am overriding the create action of the devise Registrations Controller. I have two forms for signup, individual or company, a company has a field called company_form set to true that differentiates the two forms.

Upon form validation I would like the correct form to render (previously it was going back to the default form no matter what form i was using).

I am having an issue where just the partial is being rendered (obvious as i am only rendering the partial), but I need the layouts/application file to be rendered aswell.

class RegistrationsController < Devise::RegistrationsController
  def create
  <!-- Other devise code here -->
    if resource.company_form
      render partial: 'shared/company_signup_form'
    else
      render partial: '/shared/individual_signup_form'
    end
  end
end

I have tried

if resource.company_form
    render partial: 'shared/company_signup_form', layout: 'layouts/application'
  else
    render partial: '/shared/individual_signup_form', layout: 'layouts/application
  end

But i get an error

Template is missing
Missing partial layouts/_application 

Why is it looking for a partial _application when I specified layout and how can i get the correct layout to be applied please

Thanks

Edit

Reading through the documentation it says

"Note that layouts for partials follow the same leading-underscore naming as regular partials, and are placed in the same folder with the partial that they belong to (not in the master layouts folder)."

But i want the default layout to be applied

Richlewis
  • 15,070
  • 37
  • 122
  • 283
  • layouts/application suppose to run for all the partial or any page your are rendering, this is master page of your view module. If you want different layout for two different situation then you can write one condition in application controller – Deepak Kumar Jha Sep 09 '14 at 07:51
  • well thats the thing I actually just want the master layout to render, but it doesnt – Richlewis Sep 09 '14 at 07:53
  • http://api.rubyonrails.org/classes/ActionView/PartialRenderer.html use this for ref, may this solve your problem – Deepak Kumar Jha Sep 09 '14 at 07:53
  • <%= render partial: "shared/company_signup_form", layout: "application" %> this is the right syntax – Deepak Kumar Jha Sep 09 '14 at 07:55
  • but im not in a view, im in the controller (registrations controller of devise) – Richlewis Sep 09 '14 at 07:55

4 Answers4

13

Partial rendering in a controller is most commonly used together with Ajax calls that only update one or a few elements on a page without reloading. Rendering of partials from the controller makes it possible to use the same partial template in both the full-page rendering (by calling it from within the template) and when sub-page updates happen (from the controller action responding to Ajax calls). By default, the current layout is not used.

This may be the reason your code is not working you can use rendering template.

Template rendering works just like action rendering except that it takes a path relative to the template root. The current layout is automatically applied.

if resource.company_form
   render :template => "shared/company_signup_form"
else
   render :template => "shared/individual_signup_form"   
end

** REMOVE UNDERSCORE from your partail name because you are using this as a template.

Hope this works !

Deepak Kumar Jha
  • 462
  • 6
  • 15
  • unfortunately not, the layouts/application gets rendered twice and the partial doesnt get rendered at all – Richlewis Sep 09 '14 at 08:27
  • check the edited answer, hope this will work for you – Deepak Kumar Jha Sep 09 '14 at 09:19
  • Thanks, learned something new about templates today, your answer works and is much more efficient and more "The Rails way" – Richlewis Sep 09 '14 at 09:58
  • As indicated above, you need to render your file as a template instead of as a partial if you want to have the application layout to be present in your partial. Please note to add the underscore if you use it in your filename. My example with modern syntax: render template: 'questions/_results'. – krystonen Jan 07 '20 at 15:52
6

In the end (and i know this is a hack) but i created a partial called _partial_layout_wrapper in my layouts that was an exact copy of the layouts/application file and used this in my controller

render partial: 'shared/company_signup_form', layout: 'partial_layout_wrapper'

this works but surely this cannot be the way ?

Richlewis
  • 15,070
  • 37
  • 122
  • 283
1

Could you post your whole controller? Rails renders by default layout/application.html.erb if another layout is not specified.

From the ror guides:

Partial Layouts

A partial can use its own layout file, just as a view can use a layout. For example, you might call a partial like this:

<%= render partial: "link_area", layout: "graybar" %>

This would look for a partial named _link_area.html.erb and render it using the layout _graybar.html.erb. Note that layouts for partials follow the same leading-underscore naming as regular partials, and are placed in the same folder with the partial that they belong to (not in the master layouts folder).

Also note that explicitly specifying :partial is required when passing additional options such as :layout.

So render partial: 'shared/company_signup_form', layout: 'layouts/application'is looking for layouts/_application.html.erb

0

You could use inline:

render inline: '<%= render "dir/partial" %>', layout: 'layouts/application'
estani
  • 24,254
  • 2
  • 93
  • 76