0

I'm new to Perl and DBIx::Class.

This is how I get my meaning_ids from the table translation where language = 5:

my $translations = $schema -> resultset('Translation')->search({ language => '5'});

After it I'm trying to push my data from the database into my array data:

while ( my $translation =$translations->next ) {
   push  @{ $data }, {
     meaning_id =>  $translation-> meaning 
   };
}

$self->body(encode_json $data ); 

If I do it like this, I get the following error:

encountered object 'TranslationDB::Schema::Result::Language=HASH(0x9707158)', but neither allow_blessed , convert_blessed nor allow_tags settings are enabled (or TO_JSON/FREEZE method missing)

But if I do it like that:

while ( my $translation =$translations->next ) {
   push  @{ $data }, {
     meaning_id => 0+ $translation-> meaning 
   };
}

$self->body(encode_json $data ); 

I don't get the error anymore, but the meaning is not the number out of the database. It's way too big (something like 17789000, but only numbers till 7000 are valid).

Is there an easy way to tell Perl that meaning_id is an INT and not a string?

simbabque
  • 53,749
  • 8
  • 73
  • 136
Hansanho
  • 295
  • 1
  • 3
  • 13

3 Answers3

3

It seems $translation->meaning returns an object. Using 0+ just returns its address (that's why the numbers are so high).

choroba
  • 231,213
  • 25
  • 204
  • 289
3

It's a bit hard without knowing your schema classes, but @choroba is right. The error message says $translation->meaning is an instance of TranslationDB::Schema::Result::Language. That's explained in DBIx::Class::Manual::ResultClass on CPAN.

I believe there is a relationship to a table called meaning, and when you call $translation->meaning what you get is a new result class. Instead you need to call $translation->meaning_id. Actually that would only happen in a join, but your code doesn't look like it does that.

Community
  • 1
  • 1
simbabque
  • 53,749
  • 8
  • 73
  • 136
1

It looks like there's a relationship between your translation and meaning tables. Probably, the translation table contains a foreign key to the meaning table. If you look in the Result class for your translation class then you will see that relationship defined - it will be called "meaning".

As you have that relationship, then DBIC has added a meaning method to your class which retrieves the meaning object that is associated with your translation.

But it appears that the foreign key column in your translation table is also called "meaning", so you expect calling the "meaning" method gives you the value of the foreign key rather than the associated object. Unfortunately it doesn't work like that. The relationship method overrides the column method.

This is a result of bad naming practices. I recommend that you call the primary key for every table id and the foreign key that links to another table <table_name>_id - so the column in your translation table would be called meaning_id. That way you can distinguish between the value of the key ($translation->meaning_id) and the associated meaning object ($translation->meaning).

A work-around you can use if you can't rename columns, is to use the get_column method - $translation->get_column('meaning').

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • Thanks mate! Nice explanation! Helped me to understand why this happened! I didnt create this database, but if i will create one i will remeber what you mentioned! – Hansanho Oct 14 '15 at 10:19