2016-04-30 10 views
0

Ich habe 3 Rollen für Benutzer, nennen Sie es Standard, Premium und Admin. Jeder kann Beiträge posten. Premium und Admin können wählen, ob sie private Posts oder nicht private Posts machen wollen (privat: false oder private: true). Standardbenutzer können nicht wählen, ob ihre Post privat ist/nicht; Standardmäßig haben alle Posts von Standardbenutzern den Status "Private: nil".Ruby on Rails ternären Operator zu BEIDE Null und falsch

Fassen wir zusammen:

  • Beiträge Standard Benutzer immer privat sein: nil
  • Premium/Admin Beiträge des Benutzers entweder privat sein kann: true oder privat: false

ich bin versucht, einen Bereich erstellen, so dass, wenn ein Standardbenutzer die Indexseite anschaut, Beiträge mit Private: nil und Private: false angezeigt werden, während Premium- und Admin-Benutzer alle anzeigen können. Mein Problem ist, ich kann nicht mit ternären Operatoren kommen, die Standardbenutzer erlaubt, sowohl private: nil als auch private: false Posts zu sehen. Diese

ist, was ich habe auf Beitrag Modell:

scope :visible_to, -> (user) { user.admin? || user.premium? ? all : where(private: false) || where(private: nil)} 

Der obige Code zeigt nur Beiträge mit Privat: false. Ich habe versucht, verschiedene Kombination:

... where(private: false || nil)} 

Zeigt nur privat: false Beiträge

... where(private: nil || false)} 

Zeigt nur privat: nil Beiträge

... where(private: nil && false)} 

Zeigt nur privat: nil Beiträge

... where(private: false && nil)} 

Zeigt nur privat: false Beiträge

und mehrere andere Kombinationen -

Ich habe auch bemerkt, dass, wenn ich die Reihenfolge falsch und Null geschaltet, es unterschiedliche Ergebnisse angezeigt werden. Ich dachte || oder & & Operatoren sind nicht-kommutative. Vielleicht gibt es etwas über Scoping oder ternäre Operatoren, die mir nicht bekannt waren ...

Danke!

+0

Haben Sie darüber nachgedacht eine Berechtigungs Bibliothek wie [Pundit] (https://github.com/elabs/pundit) mit? – mysmallidea

Antwort

1

Es klingt wie Sie sich gerade fragen, wie man einen Operator in einem wo? http://guides.rubyonrails.org/active_record_querying.html

Abschnitt 2.3.3 Subset Bedingungen

... where(private: [false, nil])} 

Dies sollte es in die SQL konvertieren

WHERE private in (false, nil) 

Welche Abkürzung für mehrere oder Anweisungen in SQL ist. Sie können auch Arel-Tabellen für erweiterte SQL-Funktionen verwenden, ohne auf reine SQL-Strings zu verzichten. Kasse aus diesem Artikel über Ihren Fall mit IN zusammen mit Arel Beispielen

https://robots.thoughtbot.com/using-arel-to-compose-sql-queries

# It even handles arrays containing nil! 
where(foo: ['bar', 'baz', nil]) # => (WHERE foo IN ('bar', 'baz') OR foo IS NULL) 
+0

Es funktionierte wie Magie !! (oder vielleicht war es Magie selbst ...) Danke !! – Iggy

0

Für mich sind die Bereiche mehr dazu bestimmt, ein Stück Ihres Datenmodells zu vermitteln. Die Logik davon sollte entweder in einem Modell oder Controller sein, abhängig von Ihren Einstellungen und Vorlieben. Hier ist eine allgemeine Empfehlung.

Für den Nullwert würde ich einen Standardwert für diese Spalte festlegen und alle Ihre aktuellen Nullwerte auf False migrieren. Es wird Ihr Leben leichter machen, einen definitiven Wert für diese zu haben, anstatt zu folgern, dass nil falsch oder unentschieden bedeutet.

Dann lassen Sie Ihre Service-Objekt oder Controller die Beziehung zwischen den Benutzern in der Lage, private Beiträge zu sehen.

+0

Niemals daran gedacht, es so zu machen. Vielen Dank! – Iggy