# Partial :object vs instance var

**URL:** <https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479>\
**Category:** Rails\
**Created:** [October 17, 2007, 10:24am UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479 "2007-10-17T10:24:12Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 17, 2007, 10:24am UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/1 "2007-10-17T10:24:12Z")

</div>

I’m questioning what appears to be a recommendation that makes no sense  
in AWDWR 2nd Ed. I get the point being made, but the actual  
convention/implementation seems to make the point ineffective.

If I have a controller Company with an action aboutus and an instance  
var of @contactInfo (a hash), and I have a view called aboutus.rhtml  
which renders a partial \_contactus.rhtml, I could simply use the  
@contactInfo instance var inside \_contactsus.rhtml.

So, about doing that, AWDWR on page 125 says:

– In the layout, we have access to the @cart instance variable that  
was set by the controller. It turns out that this is also available  
inside partials called from the layout. However, this is a bit like  
calling a method and passing it some value in a global variable. It  
works, but itâ€™s ugly coding, and it increases coupling (which in turn  
makes your programs brittle and hard to maintain).

I think for many thing this likely isn’t necessary in practice for  
things that are obviously going to be coupled anyway, but I get it. A  
view might as well be abstracted the same way any method would be. At  
least you’d want that option.

But here’s my problem…

On page 510 the book says:

– Idiomatic Rails developers use a variable named after the template  
(article in this instance). In fact, itâ€™s normal to take this a step  
further. If the object to be passed to the partial is in a controller  
instance variable with the same name as the partial, you can omit the  
:object parameter.

OK, so what that says is if I have a controller Company with an action  
aboutus and an instance var of @contactInfo (a hash), and I have a view  
called aboutus.rhtml which renders a partial \_contactInfo.rhtml (same  
name as the instance var this time), then the render command can simply  
be this:

\<%= render :partial =\> “contactInfo” %\>

Instead of having to write this:

\<%= render :partial =\> “contactInfo”, :object =\> @contactInfo %\>

So now we have a partial using the code contactInfo[‘phone’] instead of  
@contactInfo[‘phone’].

If you ask me, the fact that we required the instace var to be named  
contactInfo, and the partial to be named contactInfo and then the local  
variable to be named contactInfo has created a higher degree of  
interdependence than if we just used the instance var directly in the  
partial.

If I decide to change the instance var name in the controller, that is  
going to break the partial code in both cases. If I use the shortcut  
idiom and I changethe instance var, then I have to changethe name of the  
partial too. Where else might that break. But if I use the instance var  
directly in the partial, and changethe ivar name, then all I haveto do  
search & replace occurrences of that ivar name. Easy. fast, and fewer  
surprises as far as I can tell.

So, what about this convention/idiom according to “the Daves” have I  
missed?

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 17, 2007, 10:38am UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/2 "2007-10-17T10:38:22Z")

</div>

> OK, so what that says is if I have a controller Company with an action
> 
> \<%= render :partial =\> “contactInfo”, :object =\> @contactInfo %\>  
> You don’t need to write that. you get that for free with \<%=  
> render :partial =\> “contactInfo” %\> if @contactInfo exists.  
> You only need it if you’re doing  
> \<%= render :partial =\> “contactInfo”, :object =\>  
> @someOthercontactInfo %\>  
> partial.  
> -if you use the ivar in the partial and you change the ivar in the  
> controller, you have to change the ivar everywhere.  
> -if you don’t, but you use \<%= render :partial =\> “contactInfo” %\>  
> and you change the ivar, you just have to add :object  
> -if you don’t and you use \<%= render :partial =\>  
> “contactInfo”, :object =\> @contactInfo %\> then you just change the  
> name there  
> Change in one place vs change in 23 places

But as far as I’m concerned that’s a relatively modest convenience.  
Using the ivar means that you can’t suddenly decide that you’d like  
to show a list of companies, since \<%= render :partial =\>  
“contact\_nfo”, :collection =\> @contact\_infos %\> won’t work. It means  
that if that if you need to reuse that partial in some other place,  
eg a page where the ‘natural’ instance variable is @company then you  
have to create @contact\_info = @company.contact\_info rather then \<%=  
render :partial =\> “contactInfo”, :object =\> @company.contact\_info %\>

So yes, there’s a dependance between the name of the partial and the  
local variable that is materialised in that partial and there’s one  
between the name of the instance variable and the name of the partial  
that will just work magically with \<%= render :partial =\>  
“contactInfo” %\> but those 2 dependencies are separate. by using the  
ivar in the partial you tie both of those together and limit the  
reusability of that partial.

Fred

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 17, 2007, 11:16am UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/3 "2007-10-17T11:16:57Z")

</div>

Frederick C. wrote:

> > OK, so what that says is if I have a controller Company with an action
> > 
> > \<%= render :partial =\> “contactInfo”, :object =\> @contactInfo %\>  
> > You don’t need to write that. you get that for free with \<%=  
> > render :partial =\> “contactInfo” %\> if @contactInfo exists.  
> > You only need it if you’re doing  
> > \<%= render :partial =\> “contactInfo”, :object =\>  
> > @someOthercontactInfo %\>  
> > partial.  
> > -if you use the ivar in the partial and you change the ivar in the  
> > controller, you have to change the ivar everywhere.  
> > -if you don’t, but you use \<%= render :partial =\> “contactInfo” %\>  
> > and you change the ivar, you just have to add :object  
> > -if you don’t and you use \<%= render :partial =\>  
> > “contactInfo”, :object =\> @contactInfo %\> then you just change the  
> > name there  
> > Change in one place vs change in 23 places
> 
> But as far as I’m concerned that’s a relatively modest convenience.  
> Using the ivar means that you can’t suddenly decide that you’d like  
> to show a list of companies, since \<%= render :partial =\>  
> “contact\_nfo”, :collection =\> @contact\_infos %\> won’t work. It means  
> that if that if you need to reuse that partial in some other place,  
> eg a page where the ‘natural’ instance variable is @company then you  
> have to create @contact\_info = @company.contact\_info rather then \<%=  
> render :partial =\> “contactInfo”, :object =\> @company.contact\_info %\>
> 
> So yes, there’s a dependance between the name of the partial and the  
> local variable that is materialised in that partial and there’s one  
> between the name of the instance variable and the name of the partial  
> that will just work magically with \<%= render :partial =\>  
> “contactInfo” %\> but those 2 dependencies are separate. by using the  
> ivar in the partial you tie both of those together and limit the  
> reusability of that partial.

Thinking about it more, it seems to me the best version is to avoid the  
shortcut.

The shortcut makes the ivar, the file name, and the local var in the  
partial all dependent on the same name. If I have two controllers  
sharing the use of a partial, and each controller & accompanying view  
for whatever reason have unique ivar names for the same data that could  
be passed to the partial, then the shortcut requires having two partials  
of unique names. Partials that draw generic lists comes to mind.

If I declare :object in the render command, then whether I have two  
views, or I rename the ivar, the partial file name and internal local  
var remain undisturbed. Seems to me that this version does the best job  
at preserving the reusability of the partial from the standpoint of  
change in the controller and sharing among controllers.

I have no trouble with the abstraction to broaden reuse potential, but  
that shortcut version of render seems to ruin it no matter how I look at  
it. So, it seems odd that it’s available. Its like someone found himself  
typing the same thing over & over in :object and decided a shortcut  
would be handy, but it turns out the shortcut ruins the very reusability  
goal that he started with. At least, itooks that way to me.

Anyway, I did talk myself into at least using :object and not the ivar  
in the partial, but I also figure I’ll avoid “taking it further” with  
the shortcut.

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 17, 2007, 4:32pm UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/4 "2007-10-17T16:32:59Z")

</div>

On 10/17/07, Greg W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> makes your programs brittle and hard to maintain).  
> This is a good point. I don’t recommend using instance variables in  
> partials. Everything should be passed to the partial from the  
> template. Treat a partial like a subroutine that can be called in  
> different contexts and that you pass arguments to.

> On page 510 the book says:
> 
> – Idiomatic Rails developers use a variable named after the template  
> (article in this instance). In fact, it’s normal to take this a step  
> further. If the object to be passed to the partial is in a controller  
> instance variable with the same name as the partial, you can omit the  
> :object parameter.

That may be an idiom, but it should be avoided IMO. It’s just a  
“shorthand” way of using global variables, which carries all the  
negative features of using global variables in general.

Pass everything to partials. Don’t use instance vars in partials at all.

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 17, 2007, 10:52pm UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/5 "2007-10-17T22:52:52Z")

</div>

Bob S. wrote:

> On 10/17/07, Greg W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > makes your programs brittle and hard to maintain).  
> > This is a good point. I don’t recommend using instance variables in  
> > partials. Everything should be passed to the partial from the  
> > template. Treat a partial like a subroutine that can be called in  
> > different contexts and that you pass arguments to.

So, one last question on this. If a partial requires multiple objects,  
is the preferred way to handle that by passing a hash of objects via  
:object? Something like this:

render :partial =\> ‘x’, :object =\> {‘infoA’ =\> objectA, ‘infoB’ =\>  
objectB}

in which case I’d have a local var named x with a hash and could use  
x.infoA.someAttr

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 17, 2007, 11:08pm UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/6 "2007-10-17T23:08:49Z")

</div>

Bob S. wrote:

> On 10/17/07, Greg W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > So, one last question on this. If a partial requires multiple objects,  
> > is the preferred way to handle that by passing a hash of objects via  
> > :object? Something like this:
> > 
> > render :partial =\> ‘x’, :object =\> {‘infoA’ =\> objectA, ‘infoB’ =\>  
> > objectB}
> > 
> > in which case I’d have a local var named x with a hash and could use  
> > x.infoA.someAttr
> 
> You can do that, but it would be
> 
> x[‘infoA’].someAttr

duh, I knew that 😛

> Preferred is to pass multiple values using :locals
> 
> render :partial =\> ‘x’, :locals =\> {:infoA =\> objectA, :infoB =\>  
> objectB}
> 
> Then in the partial, you have reference separate variables:
> 
> infoA.someAttr  
> infoB.someAttr

Perfect, that’s _much_ better. I think I like that even better for a  
single object. Using the partial name as the local var bothered me. I  
get it, but wasn’t fond of it. I’d much rather have the var name  
represent what the object is.

Thx.

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [November 7, 2007, 3:11am UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/7 "2007-11-07T03:11:29Z")

</div>

May I use :collection and :locals together to handle parameters while  
rendering partial?

Thanks!

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [November 7, 2007, 3:21pm UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/8 "2007-11-07T15:21:40Z")

</div>

On Nov 6, 2007 9:10 PM, eastwoodsz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> May I use :collection and :locals together to handle parameters while  
> rendering partial?

Yes.

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 17, 2007, 10:58pm UTC](https://www.ruby-forum.com/t/partial-object-vs-instance-var/117479/9 "2007-10-17T22:58:39Z")

</div>

On 10/17/07, Greg W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> So, one last question on this. If a partial requires multiple objects,  
> is the preferred way to handle that by passing a hash of objects via  
> :object? Something like this:
> 
> render :partial =\> ‘x’, :object =\> {‘infoA’ =\> objectA, ‘infoB’ =\>  
> objectB}
> 
> in which case I’d have a local var named x with a hash and could use  
> x.infoA.someAttr

You can do that, but it would be

x[‘infoA’].someAttr

Preferred is to pass multiple values using :locals

render :partial =\> ‘x’, :locals =\> {:infoA =\> objectA, :infoB =\>  
objectB}

Then in the partial, you have reference separate variables:

infoA.someAttr  
infoB.someAttr
