# Custom method in model

**URL:** <https://www.ruby-forum.com/t/custom-method-in-model/142658>\
**Category:** Rails\
**Created:** [July 10, 2008, 3:48am UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658 "2008-07-10T03:48:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 10, 2008, 3:48am UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/1 "2008-07-10T03:48:25Z")

</div>

Hello,

I am a RAILS beginner and have been building an application that has  
quite a few models in it. The problem I encounter is the following:

There are three models: Contig, Intergenic, Longshortgene

A contig has many intergenics and many longshortgenes.

One of the fields in Intergenic is of the form A-B, where A and B are  
Longshortgene objects.

From the intergenics view, I would like to use A and B, in separate  
calls, to find any longshortgenes that have the same geneid (A or B)  
and belong to the same contig as the intergenics object.

My intergenics controller’s “show” method is as follows:

def show  
@intergenic = Intergenic.find(params[:id])

```
genearr=@intergenic.regionid.split('-')
genearr.each do |gene|
  @longgenes = @intergenic.ls_neighborhood(gene, 'LONG')
  @shortgenes = @intergenic.ls_neighborhood(gene, 'SHORT')
  render :action => 'list'
end

```

end

My model intergenic.rb contains the following:

belongs\_to :contig

def ls\_neighborhood(geneid,genetype)  
Longshortgene.find\_by\_sql[“select l.geneid from longshortgenes l  
where l.geneid=? and l.contig\_id=? and  
l.genetype=?”,geneid,contig\_id,genetype]  
end

From the “show” view, I just try to access @longgenes and @shortgenes  
and do something with them.

Until I inserted the above blocks of code, my application was  
functional. Now I get the following error:

ArgumentError in IntergenicsController#show

wrong number of arguments (4 for 1)

RAILS\_ROOT: /Users/apati/Projects/qa  
Application Trace | Framework Trace | Full Trace

app/models/intergenic.rb:6:in `find_by_sql' app/models/intergenic.rb:6:in`ls\_neighborhood’  
app/controllers/intergenics\_controller.rb:27:in `show' app/controllers/intergenics_controller.rb:26:in`each’  
app/controllers/intergenics\_controller.rb:26:in `show’

Could someone please point out what I am doing wrong?

Thank you very much!

Amrita

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 10, 2008, 7:30am UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/2 "2008-07-10T07:30:02Z")

</div>

I believe find\_by\_sql gets wrapped in parentheses and quotes. Like so:

find\_by\_sql(“select l.geneid from longshortgenes as l where  
l.geneid=#{geneid} and l.contig\_id=#{contig\_id} and  
l.genetype=#{genetype}”)

You might want to double-check that query, but that’s the format for  
find\_by\_sql.

– Josh

amrita wrote:

> Hello,
> 
> I am a RAILS beginner and have been building an application that has  
> quite a few models in it. The problem I encounter is the following:
> 
> There are three models: Contig, Intergenic, Longshortgene
> 
> A contig has many intergenics and many longshortgenes.
> 
> One of the fields in Intergenic is of the form A-B, where A and B are  
> Longshortgene objects.
> 
> From the intergenics view, I would like to use A and B, in separate  
> calls, to find any longshortgenes that have the same geneid (A or B)  
> and belong to the same contig as the intergenics object.
> 
> My intergenics controller’s “show” method is as follows:
> 
> def show  
> @intergenic = Intergenic.find(params[:id])
> 
> ```
> genearr=@intergenic.regionid.split('-')
> genearr.each do |gene|
> @longgenes = @intergenic.ls_neighborhood(gene, 'LONG')
> @shortgenes = @intergenic.ls_neighborhood(gene, 'SHORT')
> render :action => 'list'
> end
> 
> ```
> 
> end
> 
> My model intergenic.rb contains the following:
> 
> belongs\_to :contig
> 
> def ls\_neighborhood(geneid,genetype)  
> Longshortgene.find\_by\_sql[“select l.geneid from longshortgenes l  
> where l.geneid=? and l.contig\_id=? and  
> l.genetype=?”,geneid,contig\_id,genetype]  
> end
> 
> From the “show” view, I just try to access @longgenes and @shortgenes  
> and do something with them.
> 
> Until I inserted the above blocks of code, my application was  
> functional. Now I get the following error:
> 
> ArgumentError in IntergenicsController#show
> 
> wrong number of arguments (4 for 1)
> 
> RAILS\_ROOT: /Users/apati/Projects/qa  
> Application Trace | Framework Trace | Full Trace
> 
> app/models/intergenic.rb:6:in `find_by_sql' app/models/intergenic.rb:6:in`ls\_neighborhood’  
> app/controllers/intergenics\_controller.rb:27:in `show' app/controllers/intergenics_controller.rb:26:in`each’  
> app/controllers/intergenics\_controller.rb:26:in `show’
> 
> Could someone please point out what I am doing wrong?
> 
> Thank you very much!
> 
> Amrita

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 10, 2008, 8:43pm UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/3 "2008-07-10T20:43:06Z")

</div>

Thanks Josh. The errors have gone now. But when I do the following in  
the view,

\<% @longgenes.each do |lgene| %\>  
\<%= lgene %\>  
\<% end %\>

it doesn’t print anything. I have ensured that the data is such that  
if the query is executed correctly, @longgenes will have some values  
in it.

Thanks,  
Amrita

On Jul 9, 10:30 pm, Joshua A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 10, 2008, 11:12pm UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/4 "2008-07-10T23:12:10Z")

</div>

On 10 Jul 2008, at 19:42, amrita wrote:

> Thanks Josh. The errors have gone now. But when I do the following in  
> the view,
> 
> \<% @longgenes.each do |lgene| %\>  
> \<%= lgene %\>  
> \<% end %\>  
> That’s because \<%= %\> just ends up calling to\_s on the result, and  
> to\_s on an activerecord object isn’t something you can dump straight  
> in a view (because it’s full of things like \< which makes the browser  
> go uts).

Fred

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 10, 2008, 11:16pm UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/5 "2008-07-10T23:16:19Z")

</div>

Right, so include the method you want to call on lgene:

\<% @longgenes.each do |lgene| %\>  
\<%= lgene.name %\>  
\<% end %\>

For example.

– Josh

Frederick C. wrote:

> On 10 Jul 2008, at 19:42, amrita wrote:
> 
> > Thanks Josh. The errors have gone now. But when I do the following in  
> > the view,
> > 
> > \<% @longgenes.each do |lgene| %\>  
> > \<%= lgene %\>  
> > \<% end %\>  
> > That’s because \<%= %\> just ends up calling to\_s on the result, and  
> > to\_s on an activerecord object isn’t something you can dump straight  
> > in a view (because it’s full of things like \< which makes the browser  
> > go uts).
> 
> Fred

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 11, 2008, 12:21am UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/6 "2008-07-11T00:21:16Z")

</div>

Fred and Josh, Thanks for your replies. I tried that already. It  
doesn’t print anything. I also inserted the following in the view:

\<% if @longgenes.length == 0 %\>  
 **no long genes**   
\<% end %\>

and it prints “no long genes”. So, @longgenes doesn’t contain  
anything.

I am using Aptana Studio and when I load the html page, I see the  
queries being executed on the console. I changed the query in the  
model to the following:

Longshortgene.find\_by\_sql(“SELECT \* FROM `longshortgenes` WHERE  
(`longshortgenes`.`geneid`=‘#{geneid}’ and  
`longshortgenes`.`contig_id`=#{contig\_id} and  
`longshortgenes`.`genetype`=‘#{genetype}’)”)

The queries get executed but the view finds @longgenes empty. Is there  
a problem in returning values from the model’s method to the  
controller’s method?

I executed the same queries (copied from Aptana’s console) on MySQl  
and it returns the correct number of rows from that table.

Can you see what is going wrong?

Thanks,  
Amrita

On Jul 10, 2:16 pm, Joshua A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 11, 2008, 12:55am UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/7 "2008-07-11T00:55:46Z")

</div>

Just to verify that find\_by\_sql is working correctly, I replaced the  
existing query with

Longshortgene.find\_by\_sql("SELECT \* FROM `longshortgenes`")

and it works correctly! Then there is a problem with the way the  
longer query is framed?

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 11, 2008, 1:02am UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/8 "2008-07-11T01:02:12Z")

</div>

Also, when I replace all the variables in the query with constants,  
i,e, geneid with an actual value and contig\_ig with an actual value,  
it works! When I use variables, the query is translated correctly as  
is shown on the console, but no output is obtained ☹

---

<div class="post-metadata">

**Author:** ![amrita](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/dc4da7/32.png) [@amrita](https://www.ruby-forum.com/u/amrita)\
**Post date:** [July 11, 2008, 2:04am UTC](https://www.ruby-forum.com/t/custom-method-in-model/142658/9 "2008-07-11T02:04:52Z")

</div>

OK, I made it work, but the solution was more of a hack. I moved all  
the logic to the model’s method, so that I do no pass any arguments  
from the controller to the model method call. That solved the problem.  
So now in my controller, I have,

@lsgenes = @intergenic.ls\_neighborhood

In my model, I have:

def ls\_neighborhood  
genearr=regionid.split(’-’)  
sql=“SELECT \* FROM longshortgenes WHERE  
longshortgenes.contig\_id=”+contig\_id.to\_s+" AND  
(longshortgenes.geneid=’"+genearr[0]+"’ OR  
longshortgenes.geneid=’"+genearr[1]+"’)"  
Longshortgene.find\_by\_sql(sql)  
end

So, the application works, but when you create a custom find method,  
how do you pass arguments correctly?

Thanks,  
Amrita
