2008-09-07 6 views
2

Je travaille avec une API qui fournit des données d'arrivée de bus. Pour chaque requête, je récupère (entre autres) une liste des routes desservant l'arrêt en question. Par exemple, si la liste inclut le résultat pour les itinéraires de bus n ° 1, 2 et 5, je sais que ceux-ci servent à cet arrêt.Comment puis-je augmenter un groupe d'objets et de relations ActiveRecord dans Rails?

J'ai une relation many-to-many établie entre Route et Stop, et je veux vérifier dynamiquement et mettre à jour ces associations à chaque requête. Il n'y a pas de "liste maîtresse" des routes desservant qui s'arrête, donc cela semble être le meilleur moyen d'obtenir ces données.

Je crois que la façon dont je le fais maintenant est très inefficace:

# routes is an array of [number, destination] that I build while iterating over the data 
routes.uniq.each do |route| 
    number  = route[0] 
    destination = route[1] 

    r = Route.find_by_number_and_destination(number, destination) 

    if !r 
    r = Route.new :number => number, :destination => destination 
    r.save 
    end 

    # I have to check if it already exists because I can't find a way 
    # to create a uniqueness constraint on the join table with 2 foreign keys 
    r.stops << stop unless r.stops.include? stop 
end 

En fait, je dois faire 2 choses pour chaque itinéraire que je trouve: 1) Créer si elle ne fonctionne pas existe déjà, 2) Ajoute une relation à l'arrêt en cours s'il n'existe pas déjà. Existe-t-il un meilleur moyen de le faire, par exemple en récupérant un paquet de données en mémoire et en effectuant une partie du traitement du côté de l'application, afin d'éviter la multitude d'appels de base de données que je suis en train de faire ?

Répondre

1

Si je comprends bien, vous (devriez) avoir 2 modèles. Un modèle de route et un modèle Stop.

Voilà comment je définirais ces modèles:

class Route < ActiveRecord::Base 
    has_and_belongs_to_many :stops 
    belongs_to :stop, :foreign_key => 'destination_id' 
end 

class Stop < ActiveRecorde::Base 
    has_and_belongs_to_many :routes 
end 

Et voici comment je mettrais mes tables:

create_table :routes do |t| 
    t.integer :destination_id 
    # Any other information you want to store about routes 
end 

create_table :stops do |t| 
    # Any other information you want to store about stops 
end 

create_table :routes_stops, :primary_key => [:route_id, :stop_id] do |t| 
    t.integer :route_id 
    t.integer :stop_id 
end 

Enfin, voici le code j'utiliser:

# First, find all the relevant routes, just for caching. 
Route.find(numbers) 

r = Route.find(number) 
r.destination_id = destination 
r.stops << stop 

Ceci devrait utiliser seulement quelques requêtes SQL.

0

Il y a probablement un bon moyen de nettoyer l'appel d'arrêts, mais cela nettoie un peu en supposant que je visualise correctement comment les routes sont structurées.

routes.uniq.each do |number, destination| 

    r = Route.find_or_create_by_number_and_destination(route[0], destination) 

    r.stops << stop unless r.stops.include? stop 

end