2015-06-22 22 views
6

I seguenti modelli sono collegati tramite belongs_to:Come filtrare per ID estraneo e attributo locale tramite 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 

Ecco un app Sinatra, che fornisce alcuni percorsi di API basata su questi modelli:

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 

Vorrei produrre il SensorData per un particolare sensore come qui:

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

risposta

1

io non sono sicuro di quello che si sta cercando di fare o anche se siete ancora alla ricerca di una risposta, ma qui va. Qualcosa sembra sbagliato con i modelli nell'esempio che hai qui. Sembra che parte di quello che stai facendo funzionerebbe se Sensor sa di sensor_data. Così potrebbe essere necessario aggiungere questo per Sensor classe:

has_many :sensor_data 

Anche se il singolare dei dati è dato. La classe dovrebbe essere SensorDatum. Se non è possibile cambiarlo, è necessario comunicare a Mongoid che lo class_name da aspettarsi nel has_many è attivo SensorData.

È possibile specificare foreign_key in Mongoide con belongs_to.

NON è possibile filtrare con lo belongs_to come con ActiveRecord, ma è possibile utilizzare gli ambiti al di fuori dello belongs_to per ottenere lo stesso effetto. Exampe:

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

o

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 

Quindi la query sarebbe diventato qualcosa di simile:

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

non avrò tempo di provare la soluzione di oggi - comunque vi conceda la bontà per il tuo impegno già ora. Grazie. – JJD

+0

Ho avuto il tempo di integrare la tua soluzione. Funziona come un incantesimo - grazie ancora. – JJD