Wenn A viele B hat, und C viele B hat, kann C auch viele A haben, wenn C :through benutzt. Wenn A aber viele B und B viele C hat, außerdem C zu vielen B gehört, dann kann C nicht auch viele A haben, selbst wenn B :through benutzt.
Ich wollt's nur mal erwähnt haben, sollte jemand von euch das auch mal probieren wollen.
Wie Bahnhof? Gut, dann nochmal kurz:
:through geht nicht bei hasandbelongstomany-Assoziationen.
Mein Problem:
class AccessRight
# ...
end
class AccessRightGrant
belongs_to :acces_right
belongs_to :subject,
:polymorphic => true
end
class SystemGroup
has_many :access_right_grants,
:as => :subject
has_many :access_rights,
:through => :access_right_grants
has_and_belongs_to_many :users
end
class User
has_and_belongs_to_many :system_groups
has_many :access_right_grants,
:as => :subject
has_many :user_access_rights,
:class_name => 'AccessRight'
:through => :access_right_grants
has_many :access_rights,
:class_name => 'AccessRight',
:through => system_groups
end
... geht also NICHT.
Was ich erreichen möchte, ist dies: User
hat AccessRights
, SystemGroup
hat AccessRights
, User
hat alle AccessRights
, die SystemGroup
auch hat. User.access_rights
soll also alle , nicht nur des User
's AccessRights
zurückliefern (in obigem Code sollten erstmal nur die AccessRights
der Gruppen geladen werden, nicht alle). AccessRightGrant
ist die Linking Table zwischen AccessRight
und User
/SystemGroup
, wobei letztere über die polymorphische subject
-Spalte gelinkt werden.
Dem mit o.g. Code generierten SQL nach zu urteilen, liegt das Problem bei der HABTM-Beziehung. Bestätigt hat das ein Tauchgang in den Rails-Source, der übrigens mit seinen n Metaprogrammier-Ebenen mehr als faszinierend und beeindruckend ist, wenn man sich mal etwas Zeit für ihn nimmt. Bei einer normalen has_many
-Beziehung zwischen User
und SystemGroup
könnte es funktionieren, ausprobiert habe ich das jedoch nicht.
Aber es lässt sich für alles eine Lösung finden und bis ich hierfür eine elegante Lösung gefunden habe, werde ich einfach ganz skrupellos brute-force-Methoden wie "lade alle Rechte und durchsuche das Array" benutzen. Tja, Rails, das haste nun davon :-)