# Help with RoR partial views

**URL:** <https://www.ruby-forum.com/t/help-with-ror-partial-views/146311>\
**Category:** Rails\
**Created:** [August 19, 2008, 11:17pm UTC](https://www.ruby-forum.com/t/help-with-ror-partial-views/146311 "2008-08-19T23:17:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![CrazyMenConnected](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ec9cab/32.png) [@CrazyMenConnected](https://www.ruby-forum.com/u/CrazyMenConnected)\
**Post date:** [August 19, 2008, 11:17pm UTC](https://www.ruby-forum.com/t/help-with-ror-partial-views/146311/1 "2008-08-19T23:17:16Z")

</div>

Hi, and thank you for reading this.

First of all let me explain that i am a developer learning Ruby and  
RubyOnRails for future projects, so i am basically a noob that is in  
need of some help. 🙂

I created a little RoR project (im using netbeans 6.1 as IDE, but that  
should make no difference), that is a very simple product management  
web app.  
I created it using scaffolding, and CRUD works just fine when called  
from the views that the scaffold created. I have some other  
controller, the “main” controller with a “welcome” view. This  
controller is not tied to any model since it only exists has the  
welcome page for the site.

My problem is that i wanted to call the “new” view from “welcome” view  
using render :partial=\>“products/new”, but when ever i call it from  
there it gives me an error.

I would like that this partial view would work just like any other  
view.  
How can i do this?

sample code is bellow

products.rb

`class Product < ActiveRecord::Base
  validates_uniqueness_of :name
end
`

products\_controller.rb

[code=]class ProductsController \< ApplicationController

# GET /products

# GET /products.xml

def index  
@products = Product.find(:all)

```
respond_to do |format|
  format.html # index.html.erb
  format.xml { render :xml => @products }
end

```

end

# GET /products/1

# GET /products/1.xml

def show  
@product = Product.find(params[:id])

```
respond_to do |format|
  format.html # show.html.erb
  format.xml { render :xml => @product }
end

```

end

# GET /products/new

# GET /products/new.xml

def new  
@product = Product.new

```
respond_to do |format|
  format.html # new.html.erb
  format.xml { render :xml => @product }
end

```

end

# GET /products/1/edit

def edit  
@product = Product.find(params[:id])  
end

# POST /products

# POST /products.xml

def create  
@product = Product.new(params[:product])

```
respond_to do |format|
  if @product.save
    flash[:notice] = 'Product was successfully created.'
    format.html { redirect_to(@product) }
    format.xml { render :xml => @product, :status

```

=\> :created, :location =\> @product }  
else  
format.html { render :action =\> “new” }  
format.xml { render :xml =\> @product.errors, :status  
=\> :unprocessable\_entity }  
end  
end  
end

# PUT /products/1

# PUT /products/1.xml

def update  
@product = Product.find(params[:id])

```
respond_to do |format|
  if @product.update_attributes(params[:product])
    flash[:notice] = 'Product was successfully updated.'
    format.html { redirect_to(@product) }
    format.xml { head :ok }
  else
    format.html { render :action => "edit" }
    format.xml { render :xml => @product.errors, :status

```

=\> :unprocessable\_entity }  
end  
end  
end

# DELETE /products/1

# DELETE /products/1.xml

def destroy  
@product = Product.find(params[:id])  
@product.destroy

```
respond_to do |format|
  format.html { redirect_to(products_url) }
  format.xml { head :ok }
end

```

end  
end  
[/code]

new.html.erb

[code=]

# New product

\<% form\_for(@product) do |f| %\>  
\<%= f.error\_messages %\>

\<%= f.label :name %\>  
 \<%= f.text\_field :name %\>

\<%= f.label :price %\>  
 \<%= f.text\_field :price %\>

\<%= f.label :type %\>  
 \<%= f.text\_field :type %\>

\<%= f.submit "Create" %\>

\<% end %\>

\<%= link\_to ‘Back’, products\_path %\>  
[/code]

show.html.erb

[code=]

**Name:**  
\<%=h @product.name %\>

**Price:** \<%=h @product.price %\>

**Type:** \<%=h @product.type %\>

\<%= link\_to ‘Edit’, edit\_product\_path(@product) %\> |  
\<%= link\_to ‘Back’, products\_path %\>  
[/code]

index.html.erb

[code=]

# Listing products

\<% for product in @products %\>

\<% end %\>

| Name | Price | Type |
| --- | --- | --- |
| \<%=h product.name %\> | \<%=h product.price %\> | \<%=h product.type %\> | \<%= link\_to 'Show', product %\> | \<%= link\_to 'Edit', edit\_product\_path(product) %\> | \<%= link\_to 'Destroy', product, :confirm =\> 'Are you sure?', :method =\> :delete %\> |

  

\<%= link\_to ‘New product’, new\_product\_path %\>  
[/code]

edit.html.erb

[code=]

# Editing product

\<% form\_for(@product) do |f| %\>  
\<%= f.error\_messages %\>

\<%= f.label :name %\>  
 \<%= f.text\_field :name %\>

\<%= f.label :price %\>  
 \<%= f.text\_field :price %\>

\<%= f.label :type %\>  
 \<%= f.text\_field :type %\>

\<%= f.submit "Update" %\>

\<% end %\>

\<%= link\_to ‘Show’, @product %\> |  
\<%= link\_to ‘Back’, products\_path %\>  
[/code]

the partial view \_new.html.erb (its a copy of new.html.erb)

[code=]

# New product

\<% form\_for(@product) do |f| %\>  
\<%= f.error\_messages %\>

\<%= f.label :name %\>  
 \<%= f.text\_field :name %\>

\<%= f.label :price %\>  
 \<%= f.text\_field :price %\>

\<%= f.label :type %\>  
 \<%= f.text\_field :type %\>

\<%= f.submit "Create" %\>

\<% end %\>

\<%= link\_to ‘Back’, products\_path %\>  
[/code]

main\_controller.rb

`class MainController < ApplicationController
  def welcome
  end
end`  
welcome.html.erb

[code=]

# Main#welcome

Find me in app/views/main/welcome.html.erb

\<%= render :partial=\>“products/new” %\>  
[/code]

So my question is, shouldn’t the partial view that is being called  
from the welcome view, work just like it was being called from  
products/new view?

I am aware that this is probably not the best of examples, but imagine  
that i have a welcome page, and on that same view i would like to  
allow users to search and create new products. And show all the error  
messages on the welcome page.  
How is it done?

Thank you once more for your time!  
CrazyMenConnected

---

<div class="post-metadata">

**Author:** ![CrazyMenConnected](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ec9cab/32.png) [@CrazyMenConnected](https://www.ruby-forum.com/u/CrazyMenConnected)\
**Post date:** [August 19, 2008, 11:42pm UTC](https://www.ruby-forum.com/t/help-with-ror-partial-views/146311/2 "2008-08-19T23:42:28Z")

</div>

Heh–“it gives me an error” covers a lot of ground. 😉

I’m guessing you get a complaint about there not being a @product  
variable when you hit that form\_for call in the partial? If that’s it,  
changing your main\_controller.rb’s welcome action like so should be a  
fix:

def welcome  
@product = Product.new  
end

If my guess is wrong, write back w/the error message & stack trace.

Cheers,

-Roy

---

<div class="post-metadata">

**Author:** ![CrazyMenConnected](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ec9cab/32.png) [@CrazyMenConnected](https://www.ruby-forum.com/u/CrazyMenConnected)\
**Post date:** [August 20, 2008, 12:00am UTC](https://www.ruby-forum.com/t/help-with-ror-partial-views/146311/3 "2008-08-20T00:00:30Z")

</div>

> the partial view \_new.html.erb (its a copy of new.html.erb)  
> Although this isn’t technically wrong, it also isn’t DRY. What you would  
> actually want to do is decide what part of the new.html.erb page you  
> want to share in multiple places. Then, if it were me. I would create a  
> separate folder in the project to contain partials that will be shared  
> between different views. Maybe something like app/views/shared. In this  
> case you probably only want to share the actual form. This way any other  
> details of the page can be formatted independently (such as headings,  
> layouts, etc.).

And as mentioned previously you’ll still need to make sure you load all  
the resources the page needs from the appropriate controller action.

So new.html.erb would end up looking something like this:

#--------------------------  
new.html.erb

[code=]

# New product

\<%= render :partial =\> “shared/new\_product\_form” %\>  
#--------------------------  
Note: check that path, I wrote that off the top of my head. It may not  
be exactly correct, but should be a relative path to the location of the  
partial, wherever that might be.

And of course your welcome page would render that same partial.

Take note that the first line of the partial: \<% form\_for(@product) do  
|f| %\> accesses @product so the controller action that got you to the  
welcome page is responsible to loading that resource.

Roy P. wrote:

> Heh–“it gives me an error” covers a lot of ground. 😉
> 
> I’m guessing you get a complaint about there not being a @product  
> variable when you hit that form\_for call in the partial? If that’s it,  
> changing your main\_controller.rb’s welcome action like so should be a  
> fix:
> 
> def welcome  
> @product = Product.new  
> end
> 
> If my guess is wrong, write back w/the error message & stack trace.
> 
> Cheers,
> 
> -Roy

---

<div class="post-metadata">

**Author:** ![CrazyMenConnected](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ec9cab/32.png) [@CrazyMenConnected](https://www.ruby-forum.com/u/CrazyMenConnected)\
**Post date:** [August 20, 2008, 12:53am UTC](https://www.ruby-forum.com/t/help-with-ror-partial-views/146311/4 "2008-08-20T00:53:54Z")

</div>

Hello, and thank you for your reply.

You are right when you say the this code is not DRY. I am aware if  
lacks a bit of DRYness, but this is just a simple and fast example to  
demonstrate my question.

Has said above i changed the main\_controller and added the instance  
variable on the welcome proc with @product = Product.new.

I can render the partial fine now, but one question still remains.  
How do i redirect that partial output to the welcome view?

Because when i hit the “Create” button on the for the welcome view is  
not rendered any more, it changes to the products views.  
I would like to stay in the welcome view and that and output from the  
product partial would still be rendered on the welcome view.

How is this done?

Thanks for your help  
CrazyMenConnected

---

<div class="post-metadata">

**Author:** ![CrazyMenConnected](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ec9cab/32.png) [@CrazyMenConnected](https://www.ruby-forum.com/u/CrazyMenConnected)\
**Post date:** [August 20, 2008, 12:48am UTC](https://www.ruby-forum.com/t/help-with-ror-partial-views/146311/5 "2008-08-20T00:48:03Z")

</div>

I and thank you for your replies.

> > Heh–“it gives me an error” covers a lot of ground. 😉

Yes your right, and i am sorry for that, my message was a little  
ambiguous.

I have changed the main\_controller.rb and i’ve added the instance  
variable has you said. It now looks like this

main\_controller.rb

```auto
class MainController < ApplicationController
  def welcome
    @product = Product.new
  end
end
```

There is no error now, the partial is rendered. But now i have another  
question.  
When i press the “Create” button on the form, all of the output is  
redirected back to the products view.  
I want the error messages to the displayed on the welcome view if a  
user tried to enter the same product twice.  
Is it possible to do that? How?

---

<div class="post-metadata">

**Author:** ![CrazyMenConnected](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ec9cab/32.png) [@CrazyMenConnected](https://www.ruby-forum.com/u/CrazyMenConnected)\
**Post date:** [August 20, 2008, 6:29pm UTC](https://www.ruby-forum.com/t/help-with-ror-partial-views/146311/6 "2008-08-20T18:29:39Z")

</div>

Your partial uses a simple form\_for(@product) call. By default that  
will do a POST to the products/create action, which if it’s successful,  
does a redirect to products/show/\<\> (see the  
create method in your products\_controller.rb file).

My advice is to just play around w/rails for a bit & get used to its  
conventions before you try to bend it to your will. 😉

HTH,

-Roy
