# Best practice question

**URL:** <https://www.ruby-forum.com/t/best-practice-question/172763>\
**Category:** Rails\
**Created:** [July 27, 2009, 6:56pm UTC](https://www.ruby-forum.com/t/best-practice-question/172763 "2009-07-27T18:56:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ashley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/45deac/32.png) [@Ashley](https://www.ruby-forum.com/u/Ashley)\
**Post date:** [July 27, 2009, 6:56pm UTC](https://www.ruby-forum.com/t/best-practice-question/172763/1 "2009-07-27T18:56:33Z")

</div>

Hello guys!

Question:

Views should be “dumb” and models should deal with db queries…

but what if you have a situation like so

class User \< ActiveRecord::Base

def has\_relationship\_with?( other\_user )  
!relationships.find\_by\_other\_user\_id( other\_user.id ).nil?  
end  
end

and then in your view:

\<%= “Display this message” if @user.has\_relationship\_with?  
(@other\_user) %\>

Is it cool to call model methods which, in turn, query the db within  
the view or is there a better way of implementing this?

Thanks

ASH

---

<div class="post-metadata">

**Author:** ![Ashley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/45deac/32.png) [@Ashley](https://www.ruby-forum.com/u/Ashley)\
**Post date:** [July 27, 2009, 8:22pm UTC](https://www.ruby-forum.com/t/best-practice-question/172763/2 "2009-07-27T20:22:02Z")

</div>

On Jul 27, 2009, at 12:26 PM, Ashley wrote:

> def has\_relationship\_with?( other\_user )  
> the view or is there a better way of implementing this?
> 
> Thanks
> 
> ASH

This should be fine, but you might want to think about whether you  
need to “eager load” the relationships assosciation for performance.

The benefit is that your model contains the code and you can  
potentially refactor without touching your view.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Ashley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/45deac/32.png) [@Ashley](https://www.ruby-forum.com/u/Ashley)\
**Post date:** [July 27, 2009, 8:39pm UTC](https://www.ruby-forum.com/t/best-practice-question/172763/3 "2009-07-27T20:39:36Z")

</div>

You might want to memoize the results of that function to prevent  
unnecessary hits to the database during the same request.

On Mon, Jul 27, 2009 at 2:21 PM, Rob B.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> > class User \< ActiveRecord::Base
> 
> The benefit is that your model contains the code and you can

# –

Jim  
[http://www.thepeoplesfeed.com/contribute](http://www.thepeoplesfeed.com/contribute)

---

<div class="post-metadata">

**Author:** ![Ashley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/45deac/32.png) [@Ashley](https://www.ruby-forum.com/u/Ashley)\
**Post date:** [July 27, 2009, 9:29pm UTC](https://www.ruby-forum.com/t/best-practice-question/172763/4 "2009-07-27T21:29:22Z")

</div>

Hi Guys!

Thanks for both of your input.

I’ve opted for a helper method that looks something like:

module UsersHelper

def has\_relationship\_with?( other\_user )  
var\_name = “@has\_relationship\_with\_#{other\_user.id}”  
instance\_variable\_get(var\_name) || instance\_variable\_set(var\_name,  
current\_user.has\_relationship\_with?( other\_user )  
end

end

Loading all of the relationships was a little unnecessary in this case  
but making the same db query more than once per request was too so  
I’ve stuck the value in an instance variable

you reckon that’s ok?

---

<div class="post-metadata">

**Author:** ![Ashley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/45deac/32.png) [@Ashley](https://www.ruby-forum.com/u/Ashley)\
**Post date:** [July 28, 2009, 1:23am UTC](https://www.ruby-forum.com/t/best-practice-question/172763/5 "2009-07-28T01:23:26Z")

</div>

On Jul 27, 2009, at 3:21 PM, Ashley wrote:

> instance\_variable\_get(var\_name) || instance\_variable\_set(var\_name,  
> current\_user.has\_relationship\_with?( other\_user )  
> end
> 
> end
> 
> Loading all of the relationships was a little unnecessary in this case  
> but making the same db query more than once per request was too so  
> I’ve stuck the value in an instance variable
> 
> you reckon that’s ok?

Uh, a helper on the view? In this case, I’d say no.

I’m assuming that you really want to have several:

\<%= “Interesting stuff” if @user.has\_relationship\_with?(@other\_user) %\>

\<%= “Other stuff” if @user.has\_relationship\_with?(@other\_user) %\>

\<%= “Boring stuff” if @user.has\_relationship\_with?(@other\_user) %\>

pieces in your view and you don’t want 3 calls, only 1. Is that right?

If so, then your original solution may have done it. (ActiveRecord is  
pretty smart most times.)

class User \< ActiveRecord::Base  
def has\_relationship\_with?( other\_user )  
relationships.find\_by\_other\_user\_id( other\_user.id )  
end  
end

Once the relationships association is loaded, it might just get later  
results from what’s already in memory. Take a look at your log/  
development.log and see if you find entries like: (but for  
Relationship, of course)

School Load (0.000439) SELECT \* FROM “schools” WHERE  
(“schools”.“id” = 40882)  
CACHE (0.000000) SELECT \* FROM “schools” WHERE (“schools”.“id” =  
40882)  
CACHE (0.000000) SELECT \* FROM “schools” WHERE (“schools”.“id” =  
40882)

These are from a view helper (which in my case is actually an  
ActiveRecord model backed by a real _database view_ rather than a  
table) that needs to find a record for the School model.

One thing to note is that you never have to say: !object.nil?  
Just say: object  
Since ruby only considers false and nil to be “false” in a boolean  
context, it is idiomatic for predicates (i.e., methods that provide a  
yes/no answer) to return false/true or nil/object. Since  
find\_by\_other\_user\_id is already going to give you the Relationship  
object when it exists and nil otherwise, you don’t need to turn that  
into false/true.

-Rob

> > > > Question:  
> > > > end  
> > > > Thanks
> > 
> > > Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
> > > removed\_email\_address@domain.invalid
> > 
> > # –
> > 
> > Jimhttp://www.thepeoplesfeed.com/contribute

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid  
+1 513-295-4739  
Skype: rob.biedenharn
