Home > Back-end >  comparison of Symbol with 100 failed
comparison of Symbol with 100 failed

Time:09-29

I am re-writing a program called Emissions Gateway to the new version of Ruby on Rails.

I have a method that was written with syntax from a gem called Squeel and I am having a very hard time re-writing it. I have been failing at it for over 4 hours and can't seem to get it figured out.

This is the method right here, it is in a model called datalogger.rb along with the schema information for the datalogger.rb model.

# == Schema Information
#
# Table name: dataloggers
#
#  id                    :integer          not null, primary key
#  project_id            :integer
#  created_at            :datetime         not null
#  updated_at            :datetime         not null
#  original_file_name    :string(255)
#  original_content_type :string(255)
#  original_file_size    :integer
#  original_updated_at   :datetime
#  status                :string(255)      default("incomplete")
#  hours                 :integer
#  readings_total        :integer
#  readings_start        :datetime
#  readings_stop         :datetime
#  direct_upload_url     :string(255)
#  version               :string(255)
#  comments              :string(255)
#  bypass                :boolean          default(FALSE)
#  device_id             :integer
#  device_name           :string(255)
#  device_description    :string(255)
#  device_serial         :integer
#  md5                   :string(255)
#  user_id               :integer
#  reported_at           :datetime
#  user_reported_id      :integer
#  reported              :boolean

def stats(temperatures)
    unless bypass
      @temperatures = temperatures
      @stats = {}

      @cumulative_percent_at = 0
      @cumulative_readings = 0

      @temperatures.each_cons(2) do |current_n, next_n|
        # puts "Evaluating #{current_n} and #{next_n}"
        @stats["#{next_n}"] = {}

        # CHANGED v0.009 9/27/2021 Scott Milella
        # readings_at = readings.where{(temperature.gt current_n) & (temperature.lteq next_n)}.sum(:frequency)
        readings_at = Reading.where(:temperature > current_n).and(:temperature <= next_n).sum(:frequency)
        @stats["#{next_n}"][:readings] = readings_at
        # puts "Readings at: #{readings_at}"

        # @cumulative_readings = @stats.map{|_, v| v[:readings] }.sum
        # puts "Cumulative Readings: #{cumulative_readings}"

        percent_at = ((readings_at.to_f / readings_total) * 100 )
        @stats["#{next_n}"][:time_at] = percent_at
        @cumulative_percent_at  = percent_at
        # puts "Percent at: #{percent_at}%"

        # puts "Cumulative Percent at: #{@cumulative_percent_at}"

        percent_over = 100 - @cumulative_percent_at
        @stats["#{next_n}"][:over] = percent_over
        # puts "Percent Over: #{percent_over}%"

        # puts "Progress: #{@cumulative_readings}/#{readings_total} readings"
      end
    end

This is the method I changed:

readings_at = Reading.where(:temperature > current_n)
.and(:temperature <= next_n).sum(:frequency)      

You can see what I changed above in the method as well as I indicate it with # CHANGED. It is giving me this error called comparison of Symbol with 100 failed which makes NO Sense to me because the :symbol is an integer from another model called Reading.

Here is that model:

# == Schema Information
#
# Table name: readings
#
#  id            :integer          not null, primary key
#  temperature   :integer
#  frequency     :integer
#  datalogger_id :integer
#

class Reading < ActiveRecord::Base
  belongs_to :datalogger
  attr_accessible :frequency, :temperature, :datalogger_id

  validates_presence_of :frequency, :temperature, :datalogger_id
end

I don't understand why I can't compare an Integer with an Integer regardless if it is in a symbol or not? Do I have the Syntax wrong or something? It isn't giving me a syntax error. I have tried about 1000 other ways to write it and I get a variety of errors from > not found in Array to all kinds of other things. If anyone wants to see the whole datalogger.rb model I will post it, it's rather long and it seems to be just this method that the problem exists in.

Here is a single line I have captured from the SQL out of the current version of Emissions Gateway that is working: You can see the number 272 should be current_n and the 150 is the next_n I can verify those values on the better_errors console. So I don't understand where I am going wrong. I am guessing it might have something to do with the each_cons method perhaps which I do not understand.

I modified it so you could see the SQL all in one place, otherwise it was displaying as one long line. I will show it after just in case it is confusing:

2021-09-27T18:50:49.173173 00:00 app[web.1]:  (1.5ms)  SELECT SUM("readings"."frequency") 
AS sum_id FROM "readings" 
WHERE "readings"."datalogger_id" = 272 
AND (("readings"."temperature" > 100 
AND "readings"."temperature" <= 150))

The SQL as it comes out

2021-09-27T18:50:49.173173 00:00 app[web.1]:  (1.5ms)  SELECT SUM("readings"."frequency") AS sum_id FROM "readings" WHERE "readings"."datalogger_id" = 272 AND (("readings"."temperature" > 100 AND "readings"."temperature" <= 150))

If anyone can point out how I need to re-write this method I would be greatly appreciative, I have tried for hours and am getting noplace.

Here is the instructions for squeel in case anyone needs to see the instructions.

https://github.com/activerecord-hackery/squeel

I wish that gem had NEVER been written, has caused me so much pain it is unreal!

Thank You,

Scott

CodePudding user response:

Ok, let's take a deep look into your query:

readings_at = Reading.where(:temperature > current_n).and(:temperature <= next_n).sum(:frequency)

Both :temperature > current_n and :temperature <= next_m are comparing symbols (left side) with integers (right side). That's why you are getting an ArgumentError.

The Rails syntax to achieve what you are doing is:

readings_at = Reading.where('temperature > ? AND temperature <= ?', current_n, next_n).sum(:frequency)

Or, if you prefer, adding multiples where will add an AND clause to your query. So the below is equivalent:

readings_at = Reading.where('temperature > ?', current_n).where('temperature <= ?', next_n).sum(:frequency)

Using the ? guarantee that Rails is going to "clean" this input for you in order to prevent SQL injection.

  • Related