Require und Rails

Rails‘ Autoloading macht einen guten Job, so dass man Abhängigkeiten selten per Hand auflösen muss. Will man aber etwa eine bestehende Modelklasse aus einer Engine öffnen um eigenen Code zu ergänzen, so muss das Original notwendigerweise vorhanden sein:

# userengine/app/models/user

class User < ActiveRecord::Base
  belongs_to :user_group
end
# railsapp/app/models/user

require User::Engine.root.join('app', 'models', 'user')

class User < ActiveRecord::Base
  belongs_to :user_group
end

weiterlesen

Weniger Abstraktion ist manchmal mehr

Zunächst war ich kritisch: Kann ein Konferenzbeitrag über Routing-Ansätze brauchbare Erkenntnisse bieten? Schlussendlich ist das Routing ein sehr kleiner Teil und Rails liefert einen funktionierenden Ansatz mit. Performance-Sprünge im gesamten Kontext sind nicht zu erwarten.

Interessant finde ich aber, wie durch das Entfernen der Abstraktion zwischen Router und Controller wesentliche Konzepte vereinfacht werden können. So lassen sich die unschönen Before-Action-Hooks samt Only-Beschränkungen viel eleganter ausdrücken:

route.is 'users' do
  authorize_user_session!

  route.get do
    @users = User.all
    view(:index)
  end

  route.is ':id' do |id|
    @user = User.find(id)
    
    route.get do
      view(:edit)
    end
    
    route.post do
      @user.update(params[:user])
      redirect_to action: :show
    end
  end
end

weiterlesen

Konkatenation von Ruby-String-Literalen

Ich bin gerade über folgende Code-Zeile gestolpert und dachte schon etwas hilfreichem auf der Spur zu sein:

irb
2.1.3 :010 > "aaa" "bbb"
 => "aaabbb"

Es wirkt, als füge Ruby aufeinanderfolgende Strings automatisch zusammen. Leider ist diese Funktion auf reine Stringliterale beschränkt,  so dass sie in der Praxis leider kaum einen Nutzen haben dürfte:

2.1.3 :018 > "aaa" 3.to_s
SyntaxError: (irb):18: syntax error, unexpected tINTEGER, expecting end-of-input
"aaa" 3.to_s
       ^
       from ~/.rvm/rubies/ruby-2.1.3/bin/irb:11:in `<main>'

Schade drum, dennoch interessant zu wissen.

Kreative Rails-Environments

Rails-Environments sind mächtig, einfach einzurichten und schnell zu wechseln. Fast zu schade sich auf die Klassiker Test, Development und Production zu beschränken. Auch nach zehnmaligem Ändern der Mail-Einstellungen kam bei uns niemand auf die Idee, dass hier eine zweite Development-Umgebung nach Aufmerksamkeit schreit.

Mit erweitertem Horizont sind viele mehr oder weniger nützliche Umgebungen denkbar:

  • Development mit Mail-Versand um Mails im Mailprogramm zu testen
  • Development mit präkompilierten Assets
  • Development mit Production-Datenbank für Notfall-Debugging
  • Testing ohne Class-Cache um in einer Capybara-Session etwas anzupassen

Pub-/Sub-System Faye: Ein kleiner Test

Faye-Server aufsetzen und starten:

docker run -d -p 127.0.0.1:8000:8000 cravler/faye-app

Ein Browsertest auf localhost:8000/pub-sub bescheinigt mir einen Bad Request. Scheint zu laufen.

Auf einen Post-Request gibt es eine bessere Antwort:

curl http://localhost:8000/pub-sub -d 'message={"channel":"/moin", "data":"Moin!"}'
[{"channel":"/moin","successful":true}]

Docker ohne sudo

Wie wohl alle Docker-Pakete erfordert auch das PPA von Dotcloud Root-Rechte für alle Aktionen:

me ~ docker ps
 FATA[0000] Get http:///var/run/docker.sock/v1.17/containers/json: dial unix /var/run/docker.sock: permission denied. Are you trying to connect to a TLS-enabled daemon without TLS?

Um dies zu umgehen, kann man den eigenen Nutzer in die Gruppe docker aufnehmen:

sudo gpasswd -a ${USER} docker
sudo service docker restart

Durch die Gruppenänderung muss man sich noch einmal ab- und anmelden, anschließend läuft Docker sudofrei.

Datenbanken im Home-Verzeichnis speichern

Mit PostgreSQL ist es sehr einfach einen Datenbank-Cluster im Home-Verzeichnis eines Nutzers anzulegen. Dies kann sehr hilfreich sein, wenn beispielsweise nur das Home-Verzeichnis verschlüsselt wird und die Datenbank nicht offen herumliegen soll.

Unter Ubuntu 14.10 installieren wir Postgre und betrachten das automatisch angelegte Standard-Cluster:

sudo apt-get install postgresql

pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
9.3 main 5432 online postgres /var/lib/postgresql/9.3/main /var/log/postgresql/postgresql-9.3-main.log

weiterlesen

Bundler is using a binstub that was created for a different gem?

In regelmäßigen Abständen wirft unsere Konfiguration aus Bundler 1.7, Rails 4.1, Rspec 2.14 und Spring 1.1 bei jedem Rails-, Rake- oder Rspec-Befehl die folgende Warnung:

Bundler is using a binstub that was created for a different gem.
This is deprecated, in future versions you may need to `bundle binstub rspec` to work around a system/bundle conflict.

Auch andere Nutzer scheinen davon verwirrt zu sein, eine klare Erklärung des Problems und seiner Lösung konnte ich bisher nicht finden. Folgender Reset der Binstubs funktioniert für mich als Workaround:

rm -rf bin/*
bundle exec spring binstub --all
bundle binstub rspec-core --force

Bracket-Balancing in Ruby

Ich kann mir nicht helfen, nach zwei Jahren Ruby sieht Java manchmal nur noch umständlich aus. Gerade bei kleinen, in sich geschlossenen Programmen sollte man die Sprache mit Bedacht wählen. Wie aufwendig kann es sein herauszufinden, ob die verschiedenen Klammerarten in einem String ausbalanciert sind? Diese Frage stellte sich auch Code Corner und lieferte diese Lösung in Java:

http://www.corejavainterviewquestions.com/code-corner-bracket-balancing/
http://www.corejavainterviewquestions.com/code-corner-bracket-balancing/

Als Rubyist juckt es da in den Fingern, das muss doch schneller gehen.

weiterlesen

Spring ohne Bin-Präfix nutzen

Spring lässt sich sehr einfach installieren: Gem eintragen und die Binstubs erzeugen:

bundle exec spring binstub --all

Um nun rake routes oder rails generate statt bin/rake routes oder bin/rails generate nutzen zu können, einfach die folgenden Funktionen in beispielsweise die bash_aliases eintragen:

rake() { if [ -f bin/rake ]; then bin/rake "$@"; else bundle exec rake "$@"; fi }
rails() { if [ -f bin/rails ]; then bin/rails "$@"; else bundle exec rails "$@"; fi }
rspec() { if [ -f bin/rspec ]; then bin/rspec "$@"; else bundle exec rspec "$@"; fi }

Mein Dankeschön für den Ansatz geht an Arne.

weiterlesen