# Invalid source reflection macro?

**URL:** <https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217>\
**Category:** Rails\
**Created:** [June 29, 2009, 2:08am UTC](https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217 "2009-06-29T02:08:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![princenamor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c0e974/32.png) [@princenamor](https://www.ruby-forum.com/u/princenamor)\
**Post date:** [June 29, 2009, 2:08am UTC](https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217/1 "2009-06-29T02:08:21Z")

</div>

I’m trying to model a somewhat complicated genetic relationship in  
Rails.

class Gene \< ActiveRecord::Base  
belongs\_to :species, :foreign\_key =\> “species\_id”, :class\_name =\>  
“Species”  
has\_many :genes\_orthogroups, :class\_name =\> ‘GenesOrthogroups’ #  
join table model  
has\_many :orthogroups, :through =\> :genes\_orthogroups  
has\_many :orthologs, :through =\> :orthogroups, :source  
=\> :genes, :conditions =\> ‘gene.species\_id != ortholog.species\_id’  
end  
class GenesOrthogroups \< ActiveRecord::Base  
belongs\_to :gene  
belongs\_to :orthogroup  
end  
class Orthogroup \< ActiveRecord::Base  
has\_many :genes\_orthogroups, :class\_name =\> ‘GenesOrthogroups’  
has\_many :genes, :through =\> :genes\_orthogroups  
belongs\_to :species\_pair, :class\_name =\> ‘SpeciesPair’, :foreign\_key  
=\> “species\_pair\_id”  
end  
class SpeciesPair \< ActiveRecord::Base  
belongs\_to :species1, :foreign\_key =\> “species1\_id”, :class\_name =\>  
‘Species’  
belongs\_to :species2, :foreign\_key =\> “species2\_id”, :class\_name =\>  
‘Species’  
has\_many :orthogroups  
end  
class Species \< ActiveRecord::Base  
has\_many :genes  
has\_many :species\_pairs, :class\_name =\> ‘SpeciesPair’  
end

I’m trying to print out a list of the orthologs with a partial. The  
list is generated with:  
def find\_ortholog\_list(gene\_id)  
ortholog\_list = []  
Gene.find(gene\_id).orthologs.each do |ortholog|  
ortholog\_list \<\< ortholog  
end  
return OrthologList.new(ortholog\_list)  
end

I get the following error message:  
Invalid source reflection macro :has\_many :through for  
has\_many :orthologs, :through =\> :orthogroups. Use :source to specify  
the source reflection.

If I change :source to :gene instead of :genes, I get:  
Could not find the source association(s) :gene in model Orthogroup.  
Try 'has\_many :orthologs, :through =\> :orthogroups, :source =\>  
'. Is it one of :genes\_orthogroups, :genes, or :species\_pair?

Essentially, any given gene should have zero, one, or multiple  
orthologs in another species. These are grouped into orthogroups, each  
consisting of genes from two species, and representing a many-to-many  
relationship. Genes in an orthogroup which are of the same species  
would be paralogs instead. Because there are more than just two  
species, a gene may participate in multiple orthogroups (up to one for  
each additional species). The generalization for ortholog/paralog is  
“homolog” or “homologue,” incidentally.

I’ve based most of this code on the p.369 explanation “Using Models as  
Join Tables” in Agile Web D. with Rails (3rd Ed). I’m not  
really sure why it fails, except for the fact that I’m trying to use  
Gene as its own source for defining orthologs. What’s the proper way  
to define this relationship?

Apologies for the complexity of the model. I couldn’t think of any  
layman’s examples.

Thanks so much,  
John

---

<div class="post-metadata">

**Author:** ![princenamor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c0e974/32.png) [@princenamor](https://www.ruby-forum.com/u/princenamor)\
**Post date:** [June 29, 2009, 5:47pm UTC](https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217/2 "2009-06-29T17:47:09Z")

</div>

The :orthologs association is the problem - Rails doesn’t support  
nesting :through associations. I recall there being a plugin around  
someplace to do it, so you may want to look into that.

Depending on what you need, a simple instance method may work as well.  
For example (on Gene):

def orthologs  
genes\_orthogroups.ortholog\_groups\_for(self).map { |g| g.gene }  
end

On GenesOrthogroup:  
named\_scope ortholog\_groups\_for { |g| { :include =\> :gene, :conditions  
=\> [‘genes.species\_id != ?’, g.species\_id] } }

(not tested, but should be close to working)

A couple general things:

- model names should be singular (GenesOrthogroup rather than  
GenesOrthogroups). Otherwise you’ll eventually run into issues.

- when writing SQL fragments in conditions, table names are plural (so  
genes.whatever rather than gene.whatever).

- the association macros have sensible defaults, so you can leave some  
options out. For instance, the :species association in Gene can be  
simplified to ‘belongs\_to :species’ - Rails will find the correct FK  
(species\_id) and class (Species).

–Matt J.

---

<div class="post-metadata">

**Author:** ![princenamor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c0e974/32.png) [@princenamor](https://www.ruby-forum.com/u/princenamor)\
**Post date:** [June 29, 2009, 6:50pm UTC](https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217/3 "2009-06-29T18:50:26Z")

</div>

I’ll look at the rest of your example later, but…

John W. wrote:

> The plural model name comes from the Agile Development book. They have  
> an example–categories\_products, linking categories to products–which  
> they turn into a model. Should it be renamed category\_product?  
> […]

If I had to choose one of those options, I’d probably use  
CategoryProduct and rename the table. However, I think neither option  
is very good. What most people here seem to recommend is this: when  
your join table becomes a model, take the time to come up with an  
appropriate name for it.

For example, in this case, we might go from Category habtm Products  
(with categories\_products table) to

class Category  
has\_many :categorizations  
has\_many :products, :through =\> :categorizations  
end

(likewise for Product)

class Categorization  
belongs\_to :category  
belongs\_to :product  
end

Choosing an appropriate name for the join model will make future  
development much easier and clearer.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![princenamor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c0e974/32.png) [@princenamor](https://www.ruby-forum.com/u/princenamor)\
**Post date:** [June 29, 2009, 6:36pm UTC](https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217/4 "2009-06-29T18:36:26Z")

</div>

The plural model name comes from the Agile Development book. They have  
an example–categories\_products, linking categories to products–which  
they turn into a model. Should it be renamed category\_product? Or is  
categories\_product correct? I’m a bit confused about this, so thanks  
for bringing it up.

I’ll look around for the plugin. Thanks so much, Matt!

John

---

<div class="post-metadata">

**Author:** ![princenamor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c0e974/32.png) [@princenamor](https://www.ruby-forum.com/u/princenamor)\
**Post date:** [June 29, 2009, 9:11pm UTC](https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217/5 "2009-06-29T21:11:59Z")

</div>

So the plugin appears to work. FYI, it’s here:  
git://github.com/ianwhite/nested\_has\_many\_through.git

Unfortunately, I’m still having trouble setting up the condition. I’ve  
renamed a few things and added appropriate associations:

class Gene \< ActiveRecord::Base  
belongs\_to :species  
has\_many :gene\_orthogroup\_linkers, :class\_name =\>  
‘GeneOrthogroupLinker’  
has\_many :orthogroups, :through =\> :gene\_orthogroup\_linkers  
has\_many :ortholog\_orthogroup\_linkers, :class\_name =\>  
‘GeneOrthogroupLinker’, :through =\> :orthogroups, :source  
=\> :gene\_orthogroup\_linkers  
has\_many :orthologs, :source =\> :gene, :through  
=\> :ortholog\_orthogroup\_linkers, :conditions =\> ‘genes.species\_id !=  
genes\_2.species\_id’  
end

GeneOrthogroupLinker is the class that used to be GenesOrthogroups.

Mysql::Error: Unknown column ‘genes\_2.species\_id’ in ‘where clause’:  
SELECT `genes`.\* FROM `genes` INNER JOIN gene\_orthogroup\_linkers ON  
( genes.id = gene\_orthogroup\_linkers.gene\_id ) INNER JOIN orthogroups  
ON ( gene\_orthogroup\_linkers.orthogroup\_id = orthogroups.id ) INNER  
JOIN gene\_orthogroup\_linkers gene\_orthogroup\_linkers\_2 ON  
( orthogroups.id = gene\_orthogroup\_linkers\_2.orthogroup\_id )  
WHERE (gene\_orthogroup\_linkers\_2.gene\_id = 556 AND genes.species\_id !  
= genes\_2.species\_id)

So, it looks to me like the problem is that it selects from genes but  
has no inner join to genes\_2, only to gene\_orthogroup\_linkers\_2. How  
do I get it to INNER JOIN genes genes\_2 ON  
( gene\_orthogroup\_linkers\_2.gene\_id = genes\_2.id AND genes.species\_id !  
= genes\_2.species\_id)?

It seems like as a work-around, I could add a species\_id column on the  
GeneOrthogroupLinker model, but that doesn’t seem like the cleanest  
solution.

Incidentally, it seems unnecessary to join with orthogroups (why not  
just join the two linkers with orthogroup\_id?). Is this easily  
fixable, or better left as-is?

I also tried the named\_scope, but it doesn’t seem right for this  
situation.

Best,  
John

---

<div class="post-metadata">

**Author:** ![princenamor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c0e974/32.png) [@princenamor](https://www.ruby-forum.com/u/princenamor)\
**Post date:** [June 30, 2009, 4:47pm UTC](https://www.ruby-forum.com/t/invalid-source-reflection-macro/171217/6 "2009-06-30T16:47:06Z")

</div>

Have you tried passing the missing join directly, via the :join  
option?

–Matt J.
