2017-11-22 1 views
1

Ich versuche, eine Reihe von Checkbox-Tags zu erstellen, damit der Benutzer sehen kann, wie viel von ihnen hat er (hat abonniert), und welche nicht.ActiveRecord alle Modell Datensätze plus diejenigen mit bestimmten Kriterien

Meine Modelle sind Benutzer, Kategorie und Einstellungen, die die has_many durch Beziehung zwischen den beiden ersten Modelle behandelt:

class User < ApplicationRecord 
    has_many :preferences 
    has_many :categories, through: :preferences 
end 

class Category < ApplicationRecord 
    has_many :preferences 
    has_many :users, through: :preferences 
end 

class Preference < ApplicationRecord 
    belongs_to :user 
    belongs_to :category 
end 

Ziel die Kategorien vorhanden alle zu bekommen und in der Lage eine zusätzliche Möglichkeit, die prüfen, wenn Benutzer hat solche Kategorien, auf diese Weise kann ich eine aktive CSS-Regel verwenden und sie anders als diejenigen anzeigen, die der Benutzer nicht hat.

Ich habe gerade versucht, alle Kategorien Namen bekommen, und auch alle Kategorien Name für die dem Benutzer entsprechen, und sie als ein Array mit mehreren 2-Elemente-Arrays innerhalb Füge- und ich so etwas wie:

[ 
    ["coffee",   "coffee"], 
    ["coworking",  "food"], 
    ["event",   "pub"], 
    ["food",   "restaurant"], 
    ["landmark",  "shop"], 
    ["nightlife",  "vacation"], 
    ["pub",   nil], 
    ["restaurant",  nil], 
    ["shop",   nil], 
    ["transportation", nil], 
    ["vacation",  nil] 
] 

wäre diese Weise gut, wenn ich sie in Namen machen übereinstimmen, da die Namen nicht nie für jedes Array wiederholt werden, vielleicht wie:

[ 
    ["coffee",   "coffee"], 
    ["coworking",  nil], 
    ["event",   nil], 
    ["food",   "food"], 
    ["landmark",  nil], 
    ["nightlife",  nil], 
    ["pub",   "pub"], 
    ["restaurant",  "restaurant"], 
    ["shop",   "shop"], 
    ["transportation", nil], 
    ["vacation",  "vacation"], 
] 

So kann ich in das, was von ihnen sind gleich Null sehen letztes (zweites) Element im Array und drucke nicht die CSS-Regel für geprüfte Elemente.

Aber es scheint, dass ich es außerhalb einer ActiveRecord Abfrage tun muss.

Gibt es eine Möglichkeit, das gewünschte Ergebnis mit ActiveRecord zu erhalten, oder muss ich es manuell behandeln oder das Schema ändern?

+1

Ich bin kein SQL-Experte, aber das klingt wie eine [ 'left_outer_joins'] (http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-left_joins) SQL-Abfrage , wäre es nicht? –

Antwort

4

Sie können es in ein paar Schritten tun.

Zuerst sollten Sie alle Kategorien

all_categories = Category.all 

dann die verschiedenen Benutzerkategorien (ich bin assumiming Sie bereits Code current_user für die Anforderung zu definieren)

@user_categories = current_user.categories 

Dann können Sie den Unterschied finden zwischen die zwei:

@non_user_categories = all_categories - @user_categories 

Die @user_categories und all_categories sind streng genommen keine Arrays - sie sind ActiveRecord::Relation Objekte. Sie können jedoch die Array-Subtraktion verwenden, um den Unterschied zu finden. Beachten Sie, dass @non_user_categories ein tatsächliches Array ist.


Sie können es eine andere Art und Weise tun, die überschüssige Aufzeichnungen vermeidet Laden, obwohl für eine kleine Daten der Performancegewinn gesetzt inkonsequent sein wird.

@user_categories = current_user.categories 

@non_user_categories = Category.joins(:preferences).where.not(
    "preferences.user_id = ?", 
    current_user.id 
) 
+0

Ich habe '@user_categories = Category.joins (: Einstellungen) .where (Einstellungen: {user_id: id})' zum Abrufen der user_categories ausprobiert, ich weiß nicht warum, aber 'where.not' tut es nicht zeige die Nicht-Benutzer-Kategorien, nur ein leeres Abfrage-Ergebnis. –

Verwandte Themen