# Is "has\_many ... :through" faster?

**URL:** <https://www.ruby-forum.com/t/is-has-many-through-faster/115414>\
**Category:** Rails\
**Created:** [September 25, 2007, 1:57am UTC](https://www.ruby-forum.com/t/is-has-many-through-faster/115414 "2007-09-25T01:57:47Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mozmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@Mozmonkey](https://www.ruby-forum.com/u/Mozmonkey)\
**Post date:** [September 25, 2007, 1:57am UTC](https://www.ruby-forum.com/t/is-has-many-through-faster/115414/1 "2007-09-25T01:57:47Z")

</div>

I have a table which maps users to photo album as hosts:

| Album table | =\> | Hosts | \<=\> | Users |

Sometimes I need to query if a user is a host of an album:

if album.hosts.include? user

Which I cannot do because “hosts” is an array of Host models – not  
users. I was wondering which solution be faster, or perform better.

This:

has\_many :host\_users, :through =\> :hosts, :source =\> :user

Or:

def host\_users

```
  # Create table as instance variable
  if !@hostUsersTbl
     hosts.each do |h|
        @hostUsersTbl[h.user.id] = h
     end
  end

  @hostUsersTbl

```

end

The first solution would make an extra call to the DB, but the second  
is manually creating the list. I guess I could also do this instead:

has\_and\_belongs\_to\_many :hosts, :class\_name =\> “User”, :join\_table  
=\> “hosts”

But then I wouldn’t have the Host model array to manipulate (i.e.  
create, delete), right? Please advise.

Thanks,  
Jeremy

---

<div class="post-metadata">

**Author:** ![Mozmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@Mozmonkey](https://www.ruby-forum.com/u/Mozmonkey)\
**Post date:** [September 25, 2007, 12:21pm UTC](https://www.ruby-forum.com/t/is-has-many-through-faster/115414/2 "2007-09-25T12:21:49Z")

</div>

Hey Jeremy,  
The way I’d do this is with a

has\_many :users, :through =\> :hosts

I’m of course presuming that the Host model belongs to album and user,  
and of course that you already have the has\_many :hosts in both  
user.rb and album.rb if not classes should look like

class Album\<ActiveRecord:Base  
has\_many :hosts  
has\_many :users, :through =\> :hosts  
end

class User\<ActiveRecord:Base  
has\_many :hosts  
has\_many :albums, :through =\> :hosts  
end

class Host\<ActiveRecord:Base  
belongs\_to :user  
belongs\_to :album  
end

I think this would be faster as it will only call the database when it  
is needed so it won’t overload your objects or your database with  
unnecessary transactions.

Hope this helps.  
Cam
