# Get data from has\_and\_belongs\_to\_many + has\_many

**URL:** <https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923>\
**Category:** Rails\
**Created:** [May 20, 2010, 4:00pm UTC](https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923 "2010-05-20T16:00:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![spitfire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a5b964/32.png) [@spitfire](https://www.ruby-forum.com/u/spitfire)\
**Post date:** [May 20, 2010, 4:00pm UTC](https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923/1 "2010-05-20T16:00:23Z")

</div>

I have 3 models, A, B and C  
and the classic 3 relations:

1. A \<— has\_and\_belongs\_to\_many —\> B

2. B has\_many C

B -\> c1  
-\> c2  
-\> c3  
…

1. C belong\_to B

C -\> a1

Question:  
How can I get C entries in relationship to an A entry ?

in other words, I have  
a = A.find id

and I want C

I have tried  
a.bs.cs (NOT correct)  
A.bs.all(:include =\> :cs) (NOT correct)

do you have any solutions ?

thank you,  
Alessandro DS

---

<div class="post-metadata">

**Author:** ![spitfire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a5b964/32.png) [@spitfire](https://www.ruby-forum.com/u/spitfire)\
**Post date:** [May 20, 2010, 4:15pm UTC](https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923/2 "2010-05-20T16:15:25Z")

</div>

On 20 May 2010 15:00, Ale Ds [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Question:  
> How can I get C entries in relationship to an A entry ?
> 
> in other words, I have  
> a = A.find id
> 
> and I want C

You need to iterate over a’s bs [1] collection, and return the related  
cs. Then probably only return uniq c records (a given c might be  
linked to more than one b…)  
This should give you what you want:

cs=[]  
a.bs.each do |b|  
cs += b.cs  
end  
cs.uniq!

and this is the same thing:  
a.bs.inject {|cs, b| sum + b.cs }.uniq

[1] This is why convention prefers Foo/Bar for example names… “a,  
b, c” doesn’t make for easy or understandable reading.

---

<div class="post-metadata">

**Author:** ![spitfire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a5b964/32.png) [@spitfire](https://www.ruby-forum.com/u/spitfire)\
**Post date:** [May 20, 2010, 6:00pm UTC](https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923/3 "2010-05-20T18:00:48Z")

</div>

On May 20, 4:13 pm, Michael P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> You need to iterate over a’s bs [1] collection, and return the related  
> cs.

I don’t think that is necessary. It should be possible to get the data  
in a single sql query.  
@cs = C.all(:joins =\> {:b =\> :as}, :conditions =\> {‘as.id = 1’})

> [1] This is why convention prefers Foo/Bar for example names… “a,  
> b, c” doesn’t make for easy or understandable reading.

I second that

---

<div class="post-metadata">

**Author:** ![spitfire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a5b964/32.png) [@spitfire](https://www.ruby-forum.com/u/spitfire)\
**Post date:** [May 20, 2010, 6:26pm UTC](https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923/4 "2010-05-20T18:26:00Z")

</div>

> Michael P. wrote:
> 
> You need to iterate over a’s bs [1] collection, and return the related  
> cs. Then probably only return uniq c records (a given c might be  
> linked to more than one b…)  
> This should give you what you want:
> 
> cs=[]  
> a.bs.each do |b|  
> cs += b.cs  
> end  
> cs.uniq!  
> This is the solution that I don’t like to use
> 
> and this is the same thing:  
> a.bs.inject {|cs, b| sum + b.cs }.uniq

this looks interesting ! (even if I have to brush up ‘inject’ 🙂 )  
but I am looking for a more simpe solution

thank you,  
Alessandro DS

> [1] This is why convention prefers Foo/Bar for example names… “a,  
> b, c” doesn’t make for easy or understandable reading.

Yes, I agree with you (the pluralization of A,B,C is unreadable)

---

<div class="post-metadata">

**Author:** ![spitfire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a5b964/32.png) [@spitfire](https://www.ruby-forum.com/u/spitfire)\
**Post date:** [May 20, 2010, 6:29pm UTC](https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923/5 "2010-05-20T18:29:47Z")

</div>

> Sharagoz wrote:  
> I don’t think that is necessary. It should be possible to get the data  
> in a single sql query.  
> @cs = C.all(:joins =\> {:b =\> :as}, :conditions =\> {‘as.id = 1’})

That 's what I was looking for,  
I was wrong because I began research from the wrong side (A instead of  
C)

Thank you very much,  
Alessandro DS

---

<div class="post-metadata">

**Author:** ![spitfire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a5b964/32.png) [@spitfire](https://www.ruby-forum.com/u/spitfire)\
**Post date:** [May 21, 2010, 8:45am UTC](https://www.ruby-forum.com/t/get-data-from-has-and-belongs-to-many-has-many/188923/6 "2010-05-21T08:45:58Z")

</div>

On 20 May 2010 16:59, Sharagoz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On May 20, 4:13 pm, Michael P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > You need to iterate over a’s bs [1] collection, and return the related  
> > cs.
> 
> I don’t think that is necessary. It should be possible to get the data  
> in a single sql query.  
> @cs = C.all(:joins =\> {:b =\> :as}, :conditions =\> {‘as.id = 1’})

If you don’t have any info apart from a\_id (in params, maybe), then  
yes, go query the DB in one hit. But if you already have your ‘a’  
eager-loaded with all its related bs and cs, then there’s not much  
sense in rebuilding a load of objects; you might as well just select  
them out of the collections you have in memory.  
Depends on your starting point.
