Symbol 与 100 的比较失败
comparison of Symbol with 100 failed
我正在 Rails 上为 Ruby 的新版本重写一个名为 Emissions Gateway 的程序。
我有一个方法是用 gem 的语法编写的,叫做 Squeel,我很难重写它。我已经失败了 4 个多小时,似乎无法弄清楚。
这就是此处的方法,它与 datalogger.rb 模型的架构信息一起位于名为 datalogger.rb 的模型中。
# == 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
这是我改的方法:
readings_at = Reading.where(:temperature > current_n)
.and(:temperature <= next_n).sum(:frequency)
你可以看到我在上面的方法中更改了什么以及我用#CHANGED 表示的。它给我这个错误,称为 comparison of Symbol with 100 failed 这对我来说没有任何意义,因为 :symbol 是来自另一个名为 Reading 的模型的整数。
这是那个模型:
# == 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
我不明白为什么我不能将整数与整数进行比较,无论它是否在符号中?我的语法有误吗?它没有给我语法错误。我已经尝试了大约 1000 种其他方法来编写它,但我遇到了各种错误,从 > not found in Array 到各种其他错误。如果有人想看整个 datalogger.rb 模型,我会 post 它,它相当长,似乎就是这个方法存在问题。
这是我从当前版本的 Emissions Gateway 的 SQL 中捕获的一行:您可以看到数字 272 应该是 current_n 而 150 是next_n 我可以在 better_errors 控制台上验证这些值。所以我不明白我哪里出错了。我猜这可能与我不理解的 each_cons 方法有关。
我修改了它,所以你可以在一个地方看到所有的 SQL,否则它显示为一长行。我会在后面展示它以防它令人困惑:
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))
出来的SQL
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))
如果有人能指出我需要如何重写此方法,我将不胜感激,我已经尝试了几个小时,但还是一无所获。
这是 squeel 的说明,以防有人需要查看说明。
https://github.com/activerecord-hackery/squeel
我希望 gem 从来没有被写过,给我带来了如此不真实的痛苦!
谢谢,
斯科特
好的,让我们深入了解一下您的查询:
readings_at = Reading.where(:temperature > current_n).and(:temperature <= next_n).sum(:frequency)
:temperature > current_n
和 :temperature <= next_m
都在比较符号(左侧)和整数(右侧)。这就是为什么您会收到 ArgumentError
.
实现你正在做的事情的Rails语法是:
readings_at = Reading.where('temperature > ? AND temperature <= ?', current_n, next_n).sum(:frequency)
或者,如果您愿意,添加倍数 where
将为您的查询添加一个 AND
子句。所以下面是等价的:
readings_at = Reading.where('temperature > ?', current_n).where('temperature <= ?', next_n).sum(:frequency)
使用 ?
保证 Rails 将为您“清理”此输入以防止 SQL 注入。
我正在 Rails 上为 Ruby 的新版本重写一个名为 Emissions Gateway 的程序。
我有一个方法是用 gem 的语法编写的,叫做 Squeel,我很难重写它。我已经失败了 4 个多小时,似乎无法弄清楚。
这就是此处的方法,它与 datalogger.rb 模型的架构信息一起位于名为 datalogger.rb 的模型中。
# == 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
这是我改的方法:
readings_at = Reading.where(:temperature > current_n)
.and(:temperature <= next_n).sum(:frequency)
你可以看到我在上面的方法中更改了什么以及我用#CHANGED 表示的。它给我这个错误,称为 comparison of Symbol with 100 failed 这对我来说没有任何意义,因为 :symbol 是来自另一个名为 Reading 的模型的整数。
这是那个模型:
# == 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
我不明白为什么我不能将整数与整数进行比较,无论它是否在符号中?我的语法有误吗?它没有给我语法错误。我已经尝试了大约 1000 种其他方法来编写它,但我遇到了各种错误,从 > not found in Array 到各种其他错误。如果有人想看整个 datalogger.rb 模型,我会 post 它,它相当长,似乎就是这个方法存在问题。
这是我从当前版本的 Emissions Gateway 的 SQL 中捕获的一行:您可以看到数字 272 应该是 current_n 而 150 是next_n 我可以在 better_errors 控制台上验证这些值。所以我不明白我哪里出错了。我猜这可能与我不理解的 each_cons 方法有关。
我修改了它,所以你可以在一个地方看到所有的 SQL,否则它显示为一长行。我会在后面展示它以防它令人困惑:
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))
出来的SQL
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))
如果有人能指出我需要如何重写此方法,我将不胜感激,我已经尝试了几个小时,但还是一无所获。
这是 squeel 的说明,以防有人需要查看说明。
https://github.com/activerecord-hackery/squeel
我希望 gem 从来没有被写过,给我带来了如此不真实的痛苦!
谢谢,
斯科特
好的,让我们深入了解一下您的查询:
readings_at = Reading.where(:temperature > current_n).and(:temperature <= next_n).sum(:frequency)
:temperature > current_n
和 :temperature <= next_m
都在比较符号(左侧)和整数(右侧)。这就是为什么您会收到 ArgumentError
.
实现你正在做的事情的Rails语法是:
readings_at = Reading.where('temperature > ? AND temperature <= ?', current_n, next_n).sum(:frequency)
或者,如果您愿意,添加倍数 where
将为您的查询添加一个 AND
子句。所以下面是等价的:
readings_at = Reading.where('temperature > ?', current_n).where('temperature <= ?', next_n).sum(:frequency)
使用 ?
保证 Rails 将为您“清理”此输入以防止 SQL 注入。