2015-06-22 29 views
6

następujące modele są połączone poprzez belongs_to:Jak filtrować według obcego id i lokalnego atrybutu przez 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 

Oto Sinatra aplikacja, która zapewnia kilka ścieżek API oparte na tych modelach:

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 

Chciałbym wyprowadzić SensorData dla konkretnego czujnika, takiego jak tutaj:

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

Odpowiedz

1

Nie jestem pewien, co próbujesz zrobić, a nawet jeśli nadal szukasz odpowiedzi, ale tutaj to idzie. Coś wydaje się nie tak z modelami z przykładu, który tu masz. Wygląda na to, że część tego, co robisz, działałaby, gdyby Sensor wiedział o sensor_data. Więc może trzeba dodać to do Sensor klasy:

has_many :sensor_data 

Choć liczba pojedyncza danych jest punkt odniesienia. Oczekuje się, że klasa będzie SensorDatum. Jeśli nie możesz tego zmienić, powinieneś powiedzieć Mongoidowi, że class_name można oczekiwać w wersji has_many pod numerem SensorData.

Możesz podać foreign_key w Mongoid z belongs_to.

NIE MOŻNA filtrować za pomocą ActiveRecord przy użyciu belongs_to, ale można użyć zakresów poza numerem belongs_to, aby uzyskać ten sam efekt. Exampe:

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

lub

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 

Więc zapytanie stanie się coś takiego:

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

nie będę miał czasu, aby wypróbować swoje rozwiązanie dzisiaj - mimo wszystko będę wam udzielić nagroda za twój wysiłek już teraz. Dziękuję Ci. – JJD

+0

Miałem czas na zintegrowanie Twojego rozwiązania. Działa jak urok - jeszcze raz dziękuję. – JJD

Powiązane problemy