如何通过 belongs_to 按外部 ID 和本地属性进行过滤?

How to filter by foreign id and local attribute via belongs_to?

以下模型通过 belongs_to 链接:

require 'mongoid'
class Sensor 
    include Mongoid::Document
    field :sensor_id, type: String
    validates_uniqueness_of :sensor_id
end

...

require 'mongoid'
require_relative 'sensor.rb'
class SensorData 
    include Mongoid::Document
    belongs_to :sensor
    field :date, type: Date
    field :ozonMax1h, type: Float
    field :ozonMax8hMittel, type: Float
    index({ date: 1, sensor_id: 1 }, { unique: true })
end

这是一个 Sinatra 应用程序,它提供了一些基于这些模型的 API 路径:

require 'sinatra'
require 'csv'
require_relative './models/sensor.rb'
require_relative './models/sensor_data.rb'

configure do
  Mongoid.load!('./mongoid.yml')
end

def prepare_for_export(sensor_data)
    converted_data = sensor_data.asc(:date).map do |e|
        {
            sensor_id: e.sensor.nil? ? :null : e.sensor.sensor_id,
            date: e.date,
            ozonMax1h: e.ozonMax1h,
            ozonMax8hMittel: e.ozonMax8hMittel
        }
    end
    converted_data
end

def convert_to_json(sensor_data)
    prepare_for_export(sensor_data).to_json
end

def convert_to_csv(sensor_data)
    data = prepare_for_export sensor_data
    csv_string = CSV.generate do |csv|
        csv << data.first.keys
        data.each do |hash|
            csv << hash.values
        end
    end
    csv_string
end

def get_recent
  max_date = SensorData.max(:date)
  SensorData.where(date: max_date)
end

def get_for_year(year)
  SensorData.where(:date.gte => Date.new(year, 1, 1)).where(:date.lte => Date.new(year, 12, 31))
end

def get_for_sensor(sensor)
  foo = SensorData.where(sensor_id: sensor)
  puts "hallo"
  return foo
end

get '/api/v1/stations' do
  content_type :json
  Sensor.all.map { |e| {sensor_id: e.sensor_id} }.to_json
end

get '/api/v1/sensordata/:year' do
  content_type :json
  convert_to_json get_for_year(params[:year].to_i)
end

get '/api/v1/sensordata/:year/csv' do
  convert_to_csv get_for_year(params[:year].to_i)
end

get '/api/v1/recent' do
  content_type :json
  convert_to_json get_recent
end

我想为特定传感器输出 SensorData,例如此处:

/api/v1/stations/:sensor_id/sensordata/:year/csv

我不确定您正在尝试做什么,或者即使您仍在寻找答案,但它就在这里。您在此处的示例中的模型似乎有问题。如果 Sensor 知道 sensor_data,那么听起来你正在做的部分工作会奏效。所以可能需要将其添加到 Sensor class:

has_many :sensor_data

虽然data的单数是datum。 class 应该是 SensorDatum。如果你不能改变它,你需要告诉 Mongoid 在 has_many 中期望的 class_name 实际上是 SensorData

您可以在 Mongoid 中使用 belongs_to 指定 foreign_key

您不能像使用 ActiveRecord 那样使用 belongs_to 进行过滤,但是您可以使用 belongs_to 之外的范围来获得相同的效果。示例:

belongs_to :sensor
scope :for_year, -> (year) { where(:date.gte => Date.new(2015,1,1)).where(:date.lte => Date.new(2015, 12, 31))}

belongs_to :sensor
def self.for_year year
  where(:date.gte => Date.new(year,1,1)).where(:date.lte => Date.new(year, 12, 31))
end

所以你的查询会变成这样:

sensor = Sensor.find_by(sensor_id: params[:sensor_id])
sensor.sensor_data.for_year(2015)