Use a postgres computed value without a column as a Ruby variable

109 Views Asked by At

I have a Hanami web application where one feature is to compare strings in the database with a user provided string. To do this, I use the postgres extension pg_trgm. The translated query condition in Ruby looks like this:

.where {similarity(:content, source_text_for_lookup) > sim_score_limit}

The problem I need to solve is to get the computed similarity score back to Ruby and present it to the user. However, the similarity score is not an attribute, since it is only relevant or it should only exist when the function is called in PG to compare the two strings.

Is there a way to do this?


EDIT 2021

I've made a change in the implementation in the Segment repo from this:

def find_by_segment_match(source_text_for_lookup, source_lang, sim_score)
  aggregate(:translation_records)
    .where(language_id: source_lang)
    .where { similarity(:content, source_text_for_lookup) > sim_score/100.00 }
    .select_append { float::similarity(:content, source_text_for_lookup).as(:similarity) }
    .order { similarity(:content, source_text_for_lookup).desc }
end

to this

def find_by_segment_match1(source_text_for_lookup, source_lang, sim_score)
  segments
    .where(language_id: source_lang)
    .where { similarity(:content, source_text_for_lookup) > sim_score/100.00 }
    .select_append { float::similarity(:content, source_text_for_lookup).as(:similarity) }
    .order { similarity(:content, source_text_for_lookup).desc }
end

So I've removed the aggregation, only now, the select_append is no longer returning the computed value as a part of the Segment record. Why would this change?

The output can be seen here.

EDIT end

Regards, Sebastjan

1

There are 1 best solutions below

2
On BEST ANSWER

At least in ROM you can append function calls, smth like

.select_append { float::similarity(:content, source_text_for_lookup).as(:similarity) }

The resulting structs should have the similarity attribute with the value you need.