Ich möchte eine Beziehung zwischen Model-Klassen modellieren, die
ähnlich wie die folgende ist. Es gibt die Klassen Compiler und System.
Ein Compiler läuft auf bestimmten Systemen und kann davon abhängig
Code für bestimmte Zielsysteme erzeugen.
Relational gedacht würde ich das so angehen
create_table :compiler_host_targets, :id => false do |t|
t.integer :compiler_id, :null => false
t.integer :host_system_id, :null => false
t.integer :target_system_id, :null => false
end
add_index :host_guest_virtualizations,
[:compiler_id, :host_system_id, :target_system_id],
:unique => true
Damit kann ich in Rails aber nicht viel anfangen, ich muss die
Beziehung “modelisieren” (und darf dabei den Primary Key (id) natürlich
nicht weglassen).
class CompilerHostTarget < ActiveRecord::Base
belongs_to :compiler
belongs_to :host_system, :class_name => ‘System’
belongs_to :target_system, :class_name => ‘System’
end
Da ich das von der Klasse Compiler aus verwenden möchte, muss die etwa
so aussehen
class Compiler < ActiveRecord::Base
has_many :host_targets, :class_name => ‘CompilerHostTarget’ do
def mappings
self.inject(Hash.new { |h, k| h[k] = [] }) do |memo, mpg|
memo[mpg.host_os] << mpg.guest_os
memo
end
end
end
end
Für die Anzeige habe ich damit alles was ich brauche
-
<% compiler.host_targets.mappings.each do |host, targets| -%>
- Host: <%= host.name %> Targets: <%= targets.to_sentence %> <% end -%>
Leider bin ich damit noch ein gutes Stück davon entfernt, diese
Beziehungen auch bearbeiten zu können. Dabei ist das geringere Problem
per Ajax oder purem JavaScript Formularelemente einzufügen und zu
entfernen. Wozu mir die passende Eingebung fehlt, ich noch nicht einmal
sicher bin, ob es überhaupt geht, das ist, wie ich die Elemente –
Selects für Hosts, Checkboxen für Targets – benennen muss, damit ich
einen Params-Hash bekomme, der so aussieht:
{ “compiler” => {
“host_targets” => [
{ “host_id” => “1”, “target_ids” => [“1”, “2”] },
{ “host_id” => “2”, “target_ids” => [“2”] }
]
}
}
Wobei auch hier die host_ids nicht das Problem sind.
...funktioniert wie gewünscht. Für die target_ids könnte man es so
versuchen – und scheitern. Denn dabei geht die Zuordnung von Targets zu
bestimmten Hosts verloren. Es kann so also nicht funktionieren und
entsprechend merkwürdig sieht der Params-Hash aus, den Rails in einem
Beispielfall mit durchaus selektierten Checkboxen produziert hat
{ “compiler” => {
“host_targets” => [
{ “target_ids” => [], “host_id” => “1” },
{ “target_ids” => [] },
{ “target_ids” => [], “host_id” => “2” },
{ “target_ids” => [] },
{ “target_ids” => [] },
{ “target_ids” => [] }
]
}
}
Soweit der Schadensbericht. Wenn mir nun jemand erklären könnte, wie es
geht…
Michael
–
Michael S.
mailto:[email protected]
http://www.schuerig.de/michael/