Hier eine kleine Sammlung von Dingen, die mir geholfen haben beim Lösen der Probleme die sich einem N00b so stellen.
Exportieren von Datensätzen ins YAML Format
Rails Fixtures sind Testdatensätze, die im relativ übersichtlichen YAML-Format gespeichert werden. Möchte man bestehende Datenbankinhalte als Testdatensätze verwenden, so können Sie direkt in YAML exportiert werden.
Ich halte mich an den Beitrag von NetManiac. Den Code habe ich nur soweit ergänzt, als dass ich das Exportieren der magischen Felder „id“, „created_at“ und „updated_at“ verhindere und den Dateinamen ändere, damit keine bestehenden Fixturen überschrieben werden.
Aufgerufen mit rake extract_fixtures['mymodel'] speichert es mymodel.dumped.yml im richtigen Verzeichnis.
Datei: libs/tasks/extract_fixtures.rake:
desc 'Create YAML test fixtures from data in an existing database.
Defaults to development database. Set RAILS_ENV to override. Use args
table and limit to dump one table and limit number of records'
task :extract_fixtures, :table, :limit, :needs => :environment do |t, args|
args.with_defaults(:table => nil, :limit => nil)
limit = args.limit.nil? ? "" : "LIMIT #{args.limit}"
sql = "SELECT * FROM %s #{limit}"
skip_tables = ["schema_info" ]
if args.table.nil?
tables = ActiveRecord::Base.connection.tables - skip_tables
else
tables = [ "#{args.table}"]
end
ActiveRecord::Base.establish_connection
tables.each do |table_name|
i = "000"
File.open("#{RAILS_ROOT}/test/fixtures/#{table_name}.dumped.yml" , 'w' ) do |file|
data = ActiveRecord::Base.connection.select_all(sql % table_name)
file.write data.inject({}) { |hash, record|
record.delete_if{|key, value| ['id', 'created_at', 'updated_at'].include?(key)}
hash["#{table_name}_#{i.succ!}"] = record
hash
}.to_yaml
end
end
end
ActiveRecord Attribute beim Auslesen mit Defaultwerten überschreiben
Wenn ein Attribut immer beim Auslesen mit eineb bestimmten Wert belegt werden soll wenn noch nichts vorhanden ist, so geht dies mittels folgendem Codefragment:
def my_attribute
read_attribute(:my_attribute) or another_attribute.capitalize+" "+yet_another_attribute
end
has_and_belongs_to_many mit Checkboxen in Fieldsets
Eine Rolle hat viele Permissions und umgekehrt. Um solche Assoziationen abzubilden, kann man collection_select verwenden, das aber leider nur ein hässliches Listfeld ausgibt. Eine ambitioniertere Variante arbeitet mit Checkboxen.

HABTM mit Checkboxen
Zuerst wird in Permission.get_indexed_by_controller ein Hash of Hashes gemacht, der als ersten Schlüssel die Überschriften hat (controller) als zweiten Schlüssel die Feldbeschriftungen mit dem Zustand als Inhalt. Folgendes Partial gibt ein Formular aus und versieht sie mit „(Un-)Check all“ Links:
<%= link_to_function 'Check all', "$$('input.permission').each(function(checkbox) { checkbox.checked = true; })" %> |
<%= link_to_function 'Uncheck all', "$$('input.permission').each(function(checkbox) { checkbox.checked = false; })" %>
<% @permissions_indexed_by_controller=Permission.get_indexed_by_controller %>
<br />
<%- for controller in @permissions_indexed_by_controller.keys -%>
<% field_set_tag controller do %>
<%- for permission in @permissions_indexed_by_controller[controller] -%>
<%= check_box_tag 'role[permission_ids][]', permission.id, @role.permissions.include?(permission),{ :id => "role_permission_ids_"+ permission.id.to_s, :class => "permission"} -%><%= permission.description %>
<%- end -%>
<% end %>
<%- end -%>
Wichtig ist, dass im entsprechenden Controller in der update Funktion ein leeres Array erzeugt wird wenn nichts übergeben wird, sonst ändert sich nichts wenn man alle Häckchen rausnimmt:
params[:role][:permission_ids] ||= []
Erzeugen eines Hash of Hashes in Ruby
Die Hash/Array implementierung in PHP ist immernoch ungeschlagen. Will man in Ruby ein Hash of Hashes machen und einen Wert mittels << hinzufügen wenn noch kein leerer Hash besteht, so tut es blöd. Insbesondere wenn man Records in einem Hash abspeichen will, hilft folgendes Idiom:
(ret[map_key] ||= []) << record