diff --git a/spec/avram/queryable_spec.cr b/spec/avram/queryable_spec.cr index f4dff1947..37a725526 100644 --- a/spec/avram/queryable_spec.cr +++ b/spec/avram/queryable_spec.cr @@ -616,6 +616,22 @@ describe Avram::Queryable do min.should eq 1 end + it "works with strings" do + UserFactory.create &.name("Third") + UserFactory.create &.name("Second") + UserFactory.create &.name("First") + min = UserQuery.new.name.select_min + min.should eq "First" + end + + it "works with floats" do + UserFactory.create &.average_score(0.7) + UserFactory.create &.average_score(0.71) + UserFactory.create &.average_score(0.52) + min = UserQuery.new.average_score.select_min + min.should eq 0.52 + end + it "works with chained where clauses" do UserFactory.create &.age(2) UserFactory.create &.age(1) @@ -648,6 +664,22 @@ describe Avram::Queryable do max.should eq 3 end + it "works with strings" do + UserFactory.create &.name("Third") + UserFactory.create &.name("Second") + UserFactory.create &.name("First") + max = UserQuery.new.name.select_max + max.should eq "Third" + end + + it "works with floats" do + UserFactory.create &.average_score(0.7) + UserFactory.create &.average_score(0.71) + UserFactory.create &.average_score(0.52) + max = UserQuery.new.average_score.select_max + max.should eq 0.71 + end + it "works with chained where clauses" do UserFactory.create &.age(2) UserFactory.create &.age(1) diff --git a/src/avram/criteria.cr b/src/avram/criteria.cr index 6633ff0c6..0155b8353 100644 --- a/src/avram/criteria.cr +++ b/src/avram/criteria.cr @@ -129,12 +129,12 @@ class Avram::Criteria(T, V) add_clause(Avram::Where::LessThanOrEqualTo.new(column, V.adapter.to_db!(value))) end - def select_min : V? - rows.exec_scalar(&.select_min(column)).as(V?) + def select_min + to_expected_type(rows.exec_scalar(&.select_min(column))) end - def select_max : V? - rows.exec_scalar(&.select_max(column)).as(V?) + def select_max + to_expected_type(rows.exec_scalar(&.select_max(column))) end def select_average : Float64? @@ -187,6 +187,18 @@ class Avram::Criteria(T, V) end end + # :nodoc: + # given the value in input it casts it to the expected output type (e.g: an PG::Int becomes a Int) + private def to_expected_type(value) + value.as(V?) + end + + # :nodoc: + # special case: PG::Numeric cannot be cast to float, so we need to explicitly call to_f on it + private def to_expected_type(value : PG::Numeric?) + value.try &.to_f64 + end + macro define_function_criteria(name, output_type = V, sql_name = nil) {% sql_name = sql_name ? sql_name.id : name.id.upcase %} def {{name}}