Rails-Datenbank in Production Environment migrieren

Nach viel zu langem Suchen, bin ich endlich auf die simple Lösung gestoßen…

Problem: Ich möchte Migrationen für eine andere Rails-Environment als die Entwicklungsumgebung ausführen, in diesem Fall für die Produktivumgebung.

Die Lösung:

rake db:migrate RAILS_ENV="production"

Share

ActiveRecord: Vorsicht bei der Massenänderung von Attributen

Rails bietet einfache Möglichkeiten um einem Objekt alle benötigten Attribute zuzuweisen. Einem ActiveRecord Model können z.B. schon bei der Instanziierung alle gewünschten Attribute aus den Request-Parametern (z.B. aus einem Formular) übergeben werden. Dieses Vorgehen nennt sich im Rails-Jargon „Mass-assignment“.

Nehmen wir an wir haben ein Model „Comment“, dass die Kommentare von Benutzern einer Webseite speichert. Um Spam vorzubeugen, sollen alle Kommentare erst nach redaktioneller Überprüfung angezeigt werden, weshalb das Model ein Attribut „reviewed“ besitzt. Nur wenn dieses den Wert „1“ hat, wird der Kommentar öffentlich angezeigt.
In der Methode für die Speicherung eines neuen Kommentars steht nun folgender Code:

  1. @comment = Comment.new(params[:comment])

Würde der Anwender den Request nun so manipulieren (z.B. durch das Einfügen eines weiteren Feldes im HTML-Formular), dass dem Host der Parameter params[:comment][:reviewed] mit dem Wert „1“ übergeben wird, wäre die redaktionelle Prüfung umgangen.

Um das zu verhindern, gibt es in ActiveRecord die Methode attr_accessible. Mit dieser kann eine Whitelist der Attribute erstellt werden, die durch Mass-assignment verändert werden dürfen. Die Methode attr_protected bietet die selbe Funktionalität, jedoch mit einem Blacklist-Verfahren, d.h. es werden Attribute definiert, die nicht verändert werden dürfen.

Im Beispiel der Kommentare, müsste man also im Model „Comment“ diesen Code hinterlegen:

  1. attr_protected(:reviewed)

Dann kann das Attribut nur noch mit dem direkten Zugriff manipuliert werden z.B:

  1. comment.reviewed = true

Ich persönlich bevorzuge übrigens das Whitelist-Verfahren, da somit Flüchtigkeitsfehler bei der Entwicklung vermieden werden können ;-)

Share

Praktische Einzeiler In Ruby

Hier ein kurzer Tipp um den Quellcode in Rails bzw. Ruby etwas übersichtlicher zu gestalten.

In dem man in Ruby einer Anweisung eine Bedingung mittels if oder unless nachstellt, kann bestimmt werden, ob die Anweisung ausgeführt wird oder nicht.

Das heißt derartiger Code

  1. if @category_id == '1'
  2.    @title = 'Home'
  3. end

wird ersetzt durch:

  1. @title = 'Home' if @category_id == '1'

Bei Verwendung von unless statt if wird die Negativität der Bedingung geprüft.

Weiterhin können mit dem Schlüsselwort and zwei Anweisungen miteinander verknüpft werden.  Ich nutze das besonders oft um die Weiterleitung und die Übergabe einer Flash-Nachricht miteinander zu verbinden:

  1. flash[:error] = 'Objekt nicht gefunden' and redirect_to(index_path)
Share