0

I am working on catalyst to design a front end for a database. I am new to perl and catalyst. I am stuck with one error in the controller.

I want to fetch gene names from one table and pass each gene name to a subroutine gene_name(call a subroutine gene_name) which will perform certain function. I some how fetched the column with gene names but they are in the form of Hash reference to other table. My call to gene_name is not working.

Any idea how to pass the values to the subroutine rather than reference? My code is as follows:

my @gene_list = $c->model('Gene::GeneTable')->search({      
},{
                column =>[qw/symbol/],
}
);
foreach my $gene (@gene_list){
push @gene_aliases, &gene_name($gene);
}

The error I am getting after executing the code is as follows:

DBIx::Class::ResultSet::find(): Can't bind a reference (MyApp::Model::Gene::GeneTable=HASH(0x7ff6d88b7c58))

UPDATED

My gene_name() subroutine is in another module which I have included in the controller. Now I have changed the for loop(in controller) as following and currently it is passing gene name to gene_name() to fetch aliases(But query remains the same):

foreach my $gene (@gene_list){
push @gene_aliases, &gene_name($gene-> symbol);
}

I am accessing the @gene_aliases in my view file as follows:

[% FOREACH g in gene_aliases -%]
[% g %]
[% END -%]

The above code is fetching hash references instead of names in the page. I am not able to display the gene names on web page.If I give [% g.symbol %] in for loop then the page would be empty with no error message.Hope this would be sufficient information for answering my question. If not I would elaborate on it.

My SQL query is as follows:

Select Symbol from GeneTable;

Thanks in advance

UPDATED2

As I am not a full time programmer, I am asking these questions on the blog. Kindly help me resolve my issues. If in case I have search form which takes gene name from user and this gene name has to be passed to the gene_name() subroutine, how do I pass this (to the controller and how to call the gene_name()). Kindly help me in resolving this issue. My form in view.tt is as follows:

<form method="post" action "[% c.uri_for('/gene')%]">
<input type="text" name="search_alias">
<input type="submit" name="alias_search" value="Search">
</form>

All my aliases are in the other table called Alias, which is been used in gene_name() subroutine.

Vika Marquez
  • 353
  • 1
  • 3
  • 12
  • First, use the keyword 'columns', not 'column'. https://metacpan.org/module/DBIx::Class::Manual::Cookbook#Using-specific-columns – Joel Aug 28 '12 at 07:31
  • I don't use DBIx::Class myself, but it seems to me the first hash argument to `search` should have some parameters, surely? Isn't the purpose of that construction to build a query the equivalent of `SELECT * FROM gene WHERE symbol = ?` – RET Sep 03 '12 at 04:58
  • @ret Sorry Ret I am not able to convey my question to you properly. Please see the updated question – user1462804 Sep 03 '12 at 05:23

1 Answers1

1

Either the gene_name() function needs to expect a GeneTable object being passed to it, or you would call it like this: gene_name($gene->symbol).

Having said that, the Controller does not look like the right place for this, based on what limited information you've provided.

It would make a lot more sense to have gene_name as a method of Gene::GeneTable itself, ie:

package GeneTable;

...

sub gene_name {
    my $self = shift;
    my $gene_name = ... # do something with $self->symbol
    $gene_name
}

...

So that the ->gene_name method is available to any GeneTable object in any context.

UPDATE following OP's initial two comments

It sounds like gene_name() (which possibly should be called gene_aliases()) is a method of a Gene object. Putting such a conversion into a Controller does not adhere to good MVC philosophy.

Presumably you have model code somewhere - MyApp/Model/Gene/ most likely - and this sub should exist inside Gene/GeneTable.pm. Then you could use it thus:

[%- FOREACH g IN gene_list -%]
    [% g.symbol %]<br/><ul>
    [%- FOREACH gn IN g.gene_name -%]
    <li>[% gn %]</li>
    [%- END -%]
    </ul>
[%- END -%]

in your template, and anywhere else you have a GeneTable object or collection thereof.

UPDATE #2 Following updated question

DBIx:Class will return an array of objects when called in list context as you do. Perhaps you need to add some Data::Dumper->Dumper() calls to get a handle on what each step is returning to you.

I suggest you add the following line immediately after your call to ->search():

$c->log->debug("gene_list contains: ", Data::Dumper->Dumper(\@gene_list));

...and possibly the equivalent debug for @gene_aliases after you've populated that.

That might give you a clearer picture of what you're getting back from your search, but I'd hazard a guess you're getting Gene::GeneTable objects.

RET
  • 9,100
  • 1
  • 28
  • 33
  • Thanks for your reply. Kindly let me know what you meant while ssaying "Controller doesnot look like the right place for this", as I am not clear what else can be added to the controller. Let me know why the above mentioned error appears. I am able to access the gene name in my .tt file when I run the folowing loop: [%FOREACH g IN gene_list-%] [% g.symbol %]
    [% END %]
    – user1462804 Aug 28 '12 at 10:10
  • I am not understanding what is happening. It would be great if you could let me know how to proceed. I am not getting what I should add in the new subroutine to get the value(gene name). – user1462804 Aug 28 '12 at 10:18
  • Thanks for your updates.I am some how able to pass the gene names to the subroutine,but again the subroutine is returning the hash references to the call. I am not getting how to dereference it. Thanks in advance... – user1462804 Sep 03 '12 at 04:15
  • Sorry, you're not giving me much to work with. Could you perhaps update your original question and show more of the code? Also, see comment attached to original question. – RET Sep 03 '12 at 04:58
  • Thanks for your quick reply. You were right in guessing that the returned objects are GeneTable objects. I am thinking of other alternatives to call the gene_name() subroutine. Look into update2 and kindly provide your view on it. – user1462804 Sep 03 '12 at 10:53
  • Is it right to assume that one Gene can have many Aliases? Which begs the question why isn't that relationship declared via DBIx::Class, ie `Gene::GeneTable->has_many(aliases => 'Gene::GeneAlias', 'symbol');` and `Gene::GeneAlias->belongs_to(symbol => 'Gene::GeneTable', 'symbol');`. Then you simply loop through the aliases (zero to many) in the template via `FOREACH g IN gene_list; FOREACH al IN g.aliases; etc; END; END;` – RET Sep 04 '12 at 02:32
  • GeneTable is not directly connected to Gene Alias instead genetable is connected to another table called Feature which inturn is connected to GeneAlias in my schema.The Feature table has a column(primary key) which is foreign keys in both GeneTable and GeneAlias. I am afraid that I cannot fetch the aliases using g.aliases in template. This is the reason why I have written a subroutine gene_name() to fetch gene aliases. Can you suggest me a way on how to pass the value of search_alias(populated in search form) to gene_name() in the controller file . – user1462804 Sep 04 '12 at 05:16
  • If there is a m:1:m relationship between Gene and Alias via Feature, then use that via your model. `FOREACH g IN gene_list; FOREACH al IN g.feature.aliases; ...`. Putting such logic in a controller is a *bad* idea. To be honest, it's no longer clear to me whether your problem relates to data modelling, Catalyst form processing or something else entirely. If it helps, the parameter is available in `$c->req->param('search_alias')`. Perhaps if you update your question and show us the complete `gene` action sub, and what you're doing inside this `gene_name()` sub, it might be a bit clearer. – RET Sep 04 '12 at 05:40
  • Thanks Ret, The above code worked. As of now I am getting the Gene names and corresponding aliases correctly. thanks for support... – user1462804 Sep 05 '12 at 04:54