2017-09-09 3 views
0

J'ai une page sur mon site qui permet aux gens de filtrer les voitures en fonction d'un certain nombre de critères. Ces critères sont transmis via des paramètres.Convertir la méthode Rails en portée chaînable

Je veux ajouter un nouveau critère mais la logique dans le modèle qui fait cela est une méthode. Je ne peux pas ajouter cela à la logique de filtrage de mon contrôleur car tout est basé sur des requêtes Active Record et des parties chaînables. Comment puis-je convertir la méthode suivante en quelque chose qui est compatible avec mes requêtes et chaînes dans ma logique de filtre?

Méthode:

def self.new_cars_in_year(year) 
    new_cars = [] 

    Car.all.includes(:drives).each do |car| 
     years_driven_car = [] 
     c = car.drives.where("date IS NOT ?", nil) 

     c.each do |drive| 
     years_driven_car << (Date.parse drive.date).year 
     end 

     years_driven_car = years_driven_car.uniq 

     if car.unknown_drives 
     years_driven_car.shift 
     end 

     if years_driven_car.min == year 
     new_cars << car 
     end 
    end 

    new_cars 
    end 

Schéma:

ActiveRecord::Schema.define(version: 20170816154910) do 
    create_table "cars", force: :cascade do |t| 
    t.text  "notes",      limit: 65535 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.string "slug",      limit: 255 
    t.string "covering",     limit: 255 
    t.text  "style",      limit: 65535 
    t.text  "model",      limit: 65535 
    t.float "speed",      limit: 24 
    t.boolean "unknown_drives" 
    end 

    create_table "drives", force: :cascade do |t| 
    t.integer "car_id", limit: 4 
    t.string "notes",  limit: 255 
    t.string "date",  limit: 255 
    t.datetime "created_at",    null: false 
    t.datetime "updated_at",    null: false 
    end 
end 

Thankyou

Edit:

+0

Pouvez-vous ajouter vos modèles et/ou schéma essayer de reproduire votre scénario? –

+0

@ SebastiánPalma Ajout du schéma de base de données. Merci – rctneil

Répondre

0

La question que je vois est que vous voulez la chaîne une collection Car mais filtrée si la voiture n'a pas été conduite avant une année donnée. Il peut y avoir plusieurs «lecteurs» dans l'année sélectionnée, vous devez donc agréger l'année où le lecteur s'est produit.

Si tel était SQL, il serait quelque chose comme:

select cars.* from cars inner join drives on drives.car_id = cars.id 
    where YEAR(STR_TO_DATE(`drives.date`, "%m/%d/%Y")) = <some year> 
    group by cars.id 

Cela pourrait fonctionner, mais je ne suis pas au courant de votre application:

Car.joins(:drives) 
    .where('year(str_to_date(`drives.date`, "%m/%d/%Y")) = ?', year) 
    .uniq # Need to do distinct cars.id otherwise duplicate records