Quantcast
Channel: Active questions tagged ruby - Stack Overflow
Viewing all articles
Browse latest Browse all 4628

Using Arel.sql with Arel::Nodes::Case in Ruby for Dynamic subquery

$
0
0

I want to get the timestamp for a table of locations in each rows' local timezone (stored in tz_name column).

Generalized, how does one have a dynamic sql call for the timestamp in a given timezone which is stored as a column in a postgres DB table.

Additionally, the time zone for a given location may be null, so a case statement is needed to handle a default timezone.

This query works fine:

locations=Location.select(        Location.arel_table[:id],    Arel::Nodes::Case.new                    .when(                        Location.arel_table[:tz_name].eq(nil))                        .then('America/New_York')                    .else(Location.arel_table[:tz_name]).as("zone") ,        Arel::Nodes::NamedFunction.new('date_part',            [Arel::Nodes.build_quoted('hour'),            Arel.sql("(select CURRENT_TIMESTAMP AT TIME ZONE'America/New_York')"            )            ]        ).as("now_hour")    ).where(            Arel::Nodes::NamedFunction.new('date_part',            [Arel::Nodes.build_quoted('hour'),            Arel.sql("(select CURRENT_TIMESTAMP AT TIME ZONE'America/New_York')"            )            ]        ).eq(9)

However, when I try to use the case statement in the Arel.sql call, like so:

 Arel.sql("(select CURRENT_TIMESTAMP AT TIME ZONE " +                    Arel::Nodes::Case.new                    .when(                        Location.arel_table[:tz_name].eq(nil))                        .then('America/New_York')                    .else(Location.arel_table[:tz_name])+")"            ) # fails in both cases

or move the Arel.sql into the case statement, like this:

Arel::Nodes::Case.new                                                                                          .when(                                                Location.arel_table[:tz_name].eq(nil))                                                     .then(Arel.sql("(select CURRENT_TIMESTAMP AT TIME ZONE 'America/New_York')"))     #works                      .else(Arel.sql("(select CURRENT_TIMESTAMP AT TIME ZONE '#{Location.arel_table[:tz_name]}')"))  #fails

It does not work.

How can I make the call for the timestamp with a Time Zone coming from the table column data ( location.tz_name )?

SolutionAs Max suggested below:

Arel::Nodes::NamedFunction.new('date_part',            [Arel::Nodes.build_quoted('hour'),            Arel.sql("(TIMEZONE(COALESCE(locations.tz_name, 'America/New_York'), CURRENT_TIMESTAMP))")            ]        ).as("now_hour")

Viewing all articles
Browse latest Browse all 4628

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>