How to render partial view of one controller to another controller in ruby on rails

partial-views, ruby-on-rails

Solution

A couple of changes you'll need to make here. One thing I'll recommend before getting into the details is the Rails Guides for Layouts and Rendering (and the Rails Guides in general. The Layouts and Rendering Guide in particular will help you greatly with the VC part of Rails.

Now, on to the details. First, a partial is not a controller action. There is no controller method that corresponds to it. You can go about what you're trying to do in one of two ways, and both ways involve removing the `new` method from your subscriptions controller first.

First way: Initialize `@subscription` in your vendor site controller

The simplest way (in term of changes relative to what you already have) is to initialize `@subscription` in your vendor site controller's `index` method. Then, the rendered `_new` partial will know exactly what `subscription` is.

class VendorSiteController
  def index
    @subscription = Subscription.new # add this anywhere in the index method.
  end
end

Second way: Pass `@subscription` as a local to the `_new` partial

This way will involve changes to your controller, your view, and your partial. In your controller, you'll still need to make the change I gave above.

class VendorSiteController
  def index
    @subscription = Subscription.new # add this anywhere in the index method.
  end
end

Next, you'll need to make `@subscription` a local variable in your form, by simply removing the `@`.

<%= form_for(@subscription) do |f| %>
  <div class="field">
    <%= f.hidden_field @subscription.vendor_site_id, :value=>"1" %>
  </div>
  <!-- no changes to the button tag -->
<% end %>

Finally, you'll need to pass `@subscription` as `subscription` to your partial in your index view.

<%= render :partial => "subscriptions/new", :locals => { :subscription => @subscription } %>

While this way involves a lot more changes, it is much more flexible than the first way. For instance, say you want to render more than one new subscription in a page:

<% Subscription.where(condition: true).find_each do |s| %>
  <%= render :partial => "subscriptions/new", :locals => { :subscription => s } %>
<% end %>

As another example, maybe you want to use the `@subscription` variable name for something other than a new subscription, and you're going to use `@new_sub` for a new subscription instead.

<%= render :partial => "subscriptions/new", :locals => { :subscription => @new_sub } %>

Hopefully my answer helps you out! Feel free to comment if you need further clarification, and be sure to check out those Rails Guides!

Problem

Hi I am trying to implement subscribe button in vendor site so need to render a subscribe form with hidden attribute for vendor_site_id. The form work fine within the scope of subscription controller but I need to render it in vendor_site/show page as partial _new.html.erb. I couldn't figure out the way to fix this problem at my own can any body suggest me with this problem. My partial view subscriptions/_new.html.erb ``` <%= form_for(@subscription) do |f| %> <div class="field"> <%= f.hidden_field @subscription.vendor_site_id, :value=>"1" %> </div> <%= button_tag(type: 'submit', class: "btn btn-primary") do %> <i class="fa fa-user fa-fw"></i> Subscribe <% end %> <% end %> ``` Now when I render this in vendor_sites/index.html.erb ``` <h3>This is vendor site with id 1 just for the testing of subscription method</h3> <%= render :partial => "subscriptions/new" %> ``` it throws a error which says: ``` First argument in form cannot contain nil or be empty ``` which I understood so far is that I need to tell this vendor_site controller about the @subscription from other scope. But I cannot figure out how? My subscriptions class looks like this: ``` class SubscriptionsController < ApplicationController def new @subscription=Subscription.new end end ```

Original source