Methoden für Active-Record-Relationen definieren

Ein Scope in Active Record ist nichts anderes als syntaktischer Zucker für das Definieren einer Klassenmethode. Die folgenden User-Models führen zum selben Ergebnis:

class User < ActiveRecord::Base
  scope :admins, -> { where(role: "admin") }
end
class User < ActiveRecord::Base
  def self.admins
    where(role: "admin")
  end
end

Da man Scopes verketten kann drängt sich der (berechtigte) Verdacht auf, dass dies mit jeder Form von Klassenmethode möglich ist.

weiterlesen

Pakyows Ansatz für Views in Web-Applikationen

Auch wenn die Vertreter der Client-Seite den Kampf um die Frage, wo Views künftiger Web-Applikationen gerendert werden, schon lange gewonnen haben, so bleiben doch einige Diskussionspunkte offen. Was wird aus Suchmaschinen, Javascript-Verweigerern und den Nutzern von schwacher Hardware oder alter Browser? Der Schritt zur Client-Side-Web-Application ist an Konsequenzen geknüpft, die nicht jeder in Kauf nehmen möchte. Ich halte immer die Augen nach Projekten offen, die das Rendern sowohl auf Server als auch Client mit möglichst wenig Overhead ermöglichen. weiterlesen

Ruby: Testvollständigkeit testen

Eine Wissenschaft für sich im Test-Driven Development ist die Frage, wie jede einzelne Funktion getestet werden muss: Sind die Tests vollständig, hat man jeden Spezialfall bedacht? Hat man es zu gut gemeint und eine schwer überschaubare, redundante Testsuite geschaffen?

Einen recht ungewöhnlichen Weg zur Beantwortung der ersten Frage geht Markus Schirp. Sein Gem Mutant betrachtet Code und die zugehörigen, grünen Tests. Es verändert nun immer wieder bestimmte Teile des Applikations-Codes (nicht die Tests) und prüft, ob die Tests dadurch fehlschlagen. Tun sie dies nicht lässt sich schlussfolgern, dass diese Stellen des Codes nicht vollständig durch Tests abgedeckt oder tot sind. weiterlesen

YAML-Manipulation mit Python

Ich mache es zwanzig mal am Tag: t('admin.users.show.name'), die YAML-Datei öffnen, in denen sich die Übersetzungen befinden, den Pfad absuchen und ggf. fehlende Teile einfügen und zuletzt die Übersetzung hineinschreiben und speichern. Wirklich kreativ ist dabei nur das Formulieren, den Rest würde ich gern automatisieren. Dies sollte jedem Rails-Entwickler eine Hilfe sein.

Mein erster Schritt ist eine simple Kommandozeilen-Applikation, die eine YAML-Datei und einen Pfad liest, den Pfad findet oder erstellt, den aktuellen Wert anzeigt, einen neuen entgegennimmt, einträgt und alles in eine Datei schreibt. Das alles möglichst nah an Vim und Sublime, so dass man das ganze später in ein Plugin überführen kann. Somit bietet sich Python an, schon allein um mal wieder was neues zu nutzen.

weiterlesen

CanCanCan ist kein CanCan 2.0

Außerhalb meiner Wahrnehmung gibt es auf Github seit einiger Zeit ein Projekt, dass CanCan für tot erklärt und dessen Nachfolge antreten will: CanCanCan. 17 Menschen haben zum Projekt der „CanCanCommunity“ bereits beigetragen. So wird das kleine Gem von Ryan Bates, der seit längerer Zeit aufgrund gesundheitlicher Probleme ausfällt, weitergeführt. Wichtige Fixes für Rails 4 finden so ihren Weg ins Projekt.

Keine Entwicklung im CanCan-2.0-Branch

Mit CanCan hat man auch den 2.0-Branch geforkt, leider blieb dieser bisher unangetastet. Die neue Version sollte vor allem die von mir seit langem erwartete Unterstützung für Attribute mitbringen. weiterlesen

Rails 4 schützt Nutzer vor Regex-Schwachstellen

Rails 4 warnt seine Nutzer vor einer weit verbreiteten Sicherheitslücke, die durch falsche Anwendung von regulären Ausdrücken auftritt. So sind Validatoren wie der folgende nicht mehr erlaubt:

validates :phone, format: { with: /^[0-9]+$/ }

Dies wirft einen Argument-Error wie diesen:

`check_options_validity': The provided regular expression
 is using multiline anchors (^ or $), which may present a
 security risk. Did you mean to use \A and \z, or forgot 
 to add the :multiline => true option? (ArgumentError)

weiterlesen

Methoden-Ketten: Rubys Object#tap und Datenkapselung

Eine nette, mir bisher unbekannte Methode ist Rubys Object#tap, der man einen Block übergeben kann, in dem das Objekt als Argument zur Verfügung steht. Klingt im ersten Moment vielleicht unnötig, kann aber insbesondere in Views für etwas schöneren Code sorgen. Ein kleines Negativbeispiel in HAML:

%table
  %tbody
    %tr
      %td= current_company.name
      %td= current_company.owner ? "#{current_company.owner.first_name} #{current_company.owner.last_name}" : t('.unknown_owner')

weiterlesen

Formtastics I18n-Cache abschalten

Formtastic ist ein wahrer Segen, da es die Erzeugung und Lokalisierungen von Formularen in Rails dramatisch vereinfacht. Nervig ist nur, dass Änderungen an der Lokalisierungsdatei während der Entwicklung nicht übernommen werden. Grund hierfür ist ein Cache, der die recht komplexen Suchanfragen nach passenden Übersetzungen minimieren soll.

Um im Entwicklungsbetrieb nicht ständig den Server neustarten zu müssen, ergänzt man in config/initializers/formtastic.rb die folgende Zeile:

Formtastic::FormBuilder.i18n_cache_lookups = Rails.env != "development"

RSpec durch Parallelisierung beschleunigen

Mit der testgetriebenen Entwicklung gibt es vor allem ein großes Problem:

Finished in 2 minutes 32.8 seconds
547 examples, 0 failures, 4 pending

Schon in einem frühen Stadium läuft die Testsuite locker zwei Minuten. Parallel Tests will die Dauer verkürzen, indem es Tests auf mehreren Prozessorkernen gleichzeitig ausführt.

Ein wesentlicher Aspekt bei der Parallelisierung ist der gleichzeitige Zugriff unterschiedlicher Prozesse auf eine Datenbank. Das Gem behebt die auftretenden Konflikte, indem es jedem Prozess seine eigene Datenbank zuweist. Die Anzahl der Prozesse richtet sich dabei nach den verfügbaren Kernen. weiterlesen