2016-04-18 7 views
2

Kann ich ein Modell mithilfe eines aktiven Datensatzes "objects_to" mithilfe eines Felds aus einem hstore-Hash an ein anderes binden? Ich werde erarbeiten:Kann ich ActiveRecord-Beziehungen mit Feldern aus einem Hstore verwenden?

Ich habe ein User-Modell, das über STI auf einem seiner Felder zu viele verschiedene andere Benutzermodelle auf Basis von Berechtigungen unterklassiert wird:

class User < ActiveRecord::Base 
    self.inheritance_column = :role 
    #other definitions and validations 
end 

Hier ist eine solche submodel, das nightclub_boss Modell, bedeuten für administrative Benutzer für meine App:

class NightclubBoss < User 
    belongs_to :nightclub  #the boss record has a nightclub_id 
    has_one :rp_boss   #rp_boss should have a nightclub_boss_id 
    has_one :captain   #captain should have a nightclub_boss_id 
end 

die Idee dabei ist es, das User-Modell mit Informationen zu erweitern, wie:

-User hierarchy (which user reports to who; get a list of who is under who as needed through the ORM) 
-User origin (which user belongs to whatever other models are in the app) 

Also, was ich mir ausgedacht habe, um eine spärliche User-Tabelle zu vermeiden und auch viele kleine SQL-Tabellen zu vermeiden, ist ein Hstore-Feld im User-Modell namens "Hierarchy" zu erstellen und es verschiedenen Attributen zuzuordnen das Benutzermodell, das ausgefüllt werden sollte wenn und nur wenn der betreffende Benutzer Hierarchieinformationen speichern muss (das heißt, auf einer rollenabhängigen Basis; nightclub_boss sollte die gleichen Hierarchieinformationen wie andere Modelle in meiner App nicht hat):

class AddHstore < ActiveRecord::Migration 
    def self.up 
    enable_extension "hstore" 
    end 

    def self.down 
    disable_extension "hstore" 
    end 
end 

class AddHierarchyToUser < ActiveRecord::Migration 
    def change 
    add_column :users, :hierarchy, :hstore 
    add_index :users, :hierarchy, using: :gin 
    end 
end 

Ran

rake db:migrate 

Und dann fügte ich hstore_accesssor zu meinem Modell:

Gemfile:

gem "hstore_accessor" 

Benutzermodell:

class User < ActiveRecord::Base 
    self.inheritance_column = :role 
    hstore_accessor :hierarchy, nightclub_id: :integer 
    #other validations and definitions... 
end 

Alles ist so weit gut, mit fest codierten Daten zu testen:

[1] pry(main)> NightclubBoss.find(99) 
    NightclubBoss Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = $1 LIMIT 1 [["id", 99]] 
=> #<NightclubBoss:0x000000070bbb00 
id: 99, 
#...all other fields... 
role: "NightclubBoss", 
hierarchy: {"nightclub_id"=>"1"}> 

[2] pry(main)> NightclubBoss.find(99).nightclub_id 
    NightclubBoss Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = $1 LIMIT 1 [["id", 99]] 
=> 1 

So würden Sie Schienen erwarten, dass die entsprechende Nightclub.find (1) ziehen, die zu diesem Modell gebunden ist, wenn „NightclubBoss.nightclub Aufruf ", Recht? Nun, es geschieht nicht:

[3] pry(main)> NightclubBoss.find(99).nightclub 
    NightclubBoss Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = $1 LIMIT 1 [["id", 99]] 
=> nil 

Ich habe alle möglichen versucht, die Dinge zu versuchen, diese, um herauszufinden, und ich habe nicht die Antwort noch nicht gefunden, gibt es jemanden, der helfen kann?

Als Abhilfe wird mir klar, was ich tun kann:

Nightclub.find(NightclubBoss.find(99).nightclub_id) 

Und ich bekomme die Abfrage nur in Ordnung. Aber ich denke, das kann verbessert werden, würden Sie erwarten, in der Lage zu sein, NightclubBoss.find(99).nightclub

Ich denke, das kann auch eine sehr schlechte Praxis zu folgen. Wenn es eine bessere Möglichkeit gibt, die Art von Informationen zu modellieren, die ich brauche, lassen Sie es mich bitte wissen, ich schätze Ihren Rat. Vielen Dank!

+1

Haben Sie eine 'has_one: nightclub_boss' Assoziation für die Klasse Nightclub? –

+0

Netter Fang @FredWillmore, ich hatte dummerweise ein Mitglied: Nachtclub_Boss im Nachtclub. Allerdings habe ich zu has_one: nightclub_boss, und sogar has_one: nightclub_boss, class_name: "NightclubBoss", immer noch keine Würfel ... Ich denke, das hat immer noch mit der Seltsamkeit, die Felder aus json schafft ziehen. –

Antwort

0

Ich habe über Nacht gefunden, dass Postgres einen ähnlichen Datentyp namens Jsonb hat, der auch eine ähnliche Sache wie hstore in dem Sinne macht, dass Sie einen Hash in einem Feld in der relationalen Datenbank speichern.

Anscheinend ist es derzeit nicht möglich, aufgrund einer Beschränkung in Active dieses Spiel zu tun, die nur Spiele zu relationalen Datenbankfeldern beschränkt:

PostgreSQL jsonb field in ActiveRecord belongs_to association

Ich persönlich bin zufrieden mit dieser Antwort so ich Ich schließe diesen Thread, wenn niemand mehr Informationen hat, und natürlich werde ich mein Schema ändern.

Frage mich, ob Unterstützung gepatcht werden könnte?

Verwandte Themen