Screencast: Authentifizierung mit Janrain Engage

Janrain Engage bietet die Möglichkeit die Benutzer eine Seite über einen existierenden Account (Google, Facebook, etc.) anzumelden. Dadurch ist es für neue Benutzer nicht notwendig einen neuen Account auf der jeweiligen Seite anzulegen. Ryan zeigt in diesem Screencast wie Janrain Engage (RPX) in Rails-Applikationen benutzt werden können.

 

Download:

Download(13.5 MB, 6:22)
Alternativer Download für iPod & Apple TV(11.9 MB, 6:22)

 

Resourcen:

 

Quellcode:

[bash]
bundle install
rails g migration add_rpx_to_users rpx_identifier:string
rake db:migrate
[/bash]

[ruby]
# Gemfile
gem ‚devise_rpx_connectable‘

# user.rb
devise …, :rpx_connectable

# config/initializers/devise.rb
config.rpx_application_name = "railscasts"
RPXNow.api_key = "…"
[/ruby]

[html]
<!– layouts/application.html.erb –>
<%= link_to_rpx "Sign in", user_session_url %>

<%= javascript_include_rpx(user_session_url) %>

<!– or near sign up form –>
<%= embed_rpx user_session_url %>
[/html]

Scripttip: Datei- und Verzeichnis-Operationen mit Ruby

Das Bearbeiten von Dateien und Verzeichnissen ist eine sehr häufig wiederkehrende Arbeit in der Programmierung.
Daher gibt es in unserem heutigen Scripttip ein paar Tips zu diesem Thema. Wie aus anderen Bereichen bekannt, sind Zugriffe und Manipulation von Dateien und Verzeichnissen mit Ruby sehr einfach.

Im ersten Beispiel erstellen wir eine Datei. Sie wird dort angelegt von wo das Script ausgeführt wird.

Eine einfach Text-Datei erstellen:
[ruby]
datei = ‚datei.txt‘
File.open(datei, ‚w‘) {|d| d.write ‚Text für die neue Datei‘}
[/ruby]

Soll die Datei an einem bestimmten Ort/Pfad erstellt werden, müssen ggf. die entsprechenden Verzeichnisse erst angelegt werden.
Dazu kann die „mkdir_p“ Methode aus FileUtils benutzt werden, weil diese sicherstellt, dass alle benötigten Ordner im Pfad angelegt werden.

[ruby]
require ‚fileutils‘

datei = ‚/tmp/mein/pfad/zur/datei.txt‘
FileUtils.mkdir_p File.dirname(datei)
File.open(datei, ‚w‘) do |d|
d.write ‚Beispieltext für die neu erzeugte Datei‘
end
[/ruby]

Soll die Original-Datei unverändert bleiben, kann eine Kopie erzeugt werden um die Manipulationen an dieser vorzunehmen.
[ruby]
require ‚fileutils‘

FileUtils.copy(‚datei.txt‘, ‚kopie.txt‘)
[/ruby]

Auch das Verschieben einer Datei ist auch sehr einfach mit FileUtils.

[ruby]
require ‚fileutils‘

alter_pfad = "/der/alte/pfad/zur/datei.txt"
neuer_pfad = "/der/neue/ort/der/datei.txt"
# ggf. die benötigten Verzeichnisse erstellen
FileUtils.mkdir_p File.dirname(neuer_pfad)

FileUtils.mv(‚/der/alte/pfad/zur‘, ‚/opt/new/location/your_file‘)
[/ruby]

Dies ist nur ein kleiner Auszug aus den Möglichkeiten die FileUtils bietet.
Eine Liste weiterer Methoden sind in den RubyDocs verfügbar.
Neugierige können sich in der irb-Konsole einen Auszug der Methoden geben lassen.
Die meisten Funktions-Namen sind an die Unix-Kommandos angelehnt und in der Regel selbstsprechend.
[ruby]
irb(main):001:0> require ‚PP‘
=> true
irb(main):001:0> require ‚fileutils‘
=> true

irb(main):007:0> pp FileUtils.singleton_methods.sort
["cd",
"chdir",
"chmod",
"chmod_R",
"chown",
"chown_R",
"cmp",
"collect_method",
"commands",
"compare_file",
"compare_stream",
"copy",
"copy_entry",
"copy_file",
"copy_stream",
"cp",
"cp_r",
"getwd",
"have_option?",
"identical?",
"install",
"link",
"ln",
"ln_s",
"ln_sf",
"makedirs",
"mkdir",
"mkdir_p",
"mkpath",
"move",
"mv",
"options",
"options_of",
"private_module_function",
"pwd",
"remove",
"remove_dir",
"remove_entry",
"remove_entry_secure",
"remove_file",
"rm",
"rm_f",
"rm_r",
"rm_rf",
"rmdir",
"rmtree",
"safe_unlink",
"symlink",
"touch",
"uptodate?"]
=> nil
[/ruby]

Bevor wir diesen Scripttip abschließen, noch ein kleiner Tip zu temporären Dateien.
Häufig wird eine Datei nur zum „zwischenlagern“ benötigt. Das heißt die Datei wird spätestens nach der Asführung des Scripts nicht mehr benötigt.
Solche Dateien selber anzulegen, erfordert gleichzeitig, dass sie selber gelöscht werden (Aufräumscript, Cron, etc.). Weiterhin kann es zu Namenskollisionen kommen, wenn eine Datei mit dem gleichen Namen vorhanden, usw.
All diese Arbeit wird in Ruby von „Tempfile“ abgenommen und sollte für diese Zwecke eingesetzt werden.

[ruby]
require ‚tempfile‘

temp_datei = Tempfile.new(‚temporaere_datei.txt‘)
temp_datei << "Daten zum Zwischenlagern"
temp_datei.close
[/ruby]

temp_datei.close wird zwar bei Script-Ende automatisch ausgeführt, aber auf diese Weise behält man die Kontrolle.

Wir hoffen der Scripttip hilft euch bei euren zukünftigen Datei-Operationen.

Screencast: Routing in Rails 3 Teil 2

In dieser Woche gibt es noch mehr Infos und Details zu Routen in Rails 3. In diesem Screencast erklärt Ryan die Mapper Klasse.

 

Download:

Download(38.6 MB, 13:25)
Alternativer Download für iPod & Apple TV(32.7 MB, 13:25)

 

Resourcen:

 

Quellcode:

[ruby]
# routes.rb
match ‚products‘ => redirect("/items")
get ‚products/recent‘
resources :products do
collection do
get :discounted
end
end
controller :products do
match # …
end
[/ruby]

Screencast: Routing in Rails 3

Diese Woche zeigt Ryan wie Routen in Rails 3 funktionieren und wie sie aufgebaut sind.

 

Download:

Download(39.7 MB, 13:22)
Alternativer Download für iPod & Apple TV(32.9 MB, 13:22)

 

Resourcen:

 

Quellcode:

[bash]
git clone git://github.com/rails/rails.git
git checkout v3.0.0
[/bash]

[ruby]
match ‚products‘, :to => ‚products#index‘
# same as
match ‚products‘, :to => ProductsController.action("index")

match ‚products/recent‘
# same as
match ‚products/recent‘, :to =>’products#recent‘, :as => ‚products_recent‘
[/ruby]

Scripttip: Countdown in Ruby

Wie lange dauert es noch bis zum Release, Launch, Geburtstag… Die Dauer bis zu einem Event lässt sich sehr gut mit einem Countdown visualisieren. Um die Restzeit nicht selber in Minuten, Sekunden, etc. umzurechnen kann in Ruby hierfür das gem ‚chronic_duration‘ eingesetzt werden.

Falls nicht schon vorhanden muss erst das gem installiert werden:

[bash]
gem install chronic_duration # ggf. ein ’sudo‘ voranstellen
[/bash]

Wenn die Dauer für den Countdown bekannt ist, kann man diese direkt verwenden:
[ruby]
# Die benötigten Bibliotheken
require ‚rubygems‘
require ‚chronic_duration‘
require ‚time‘

dauer = 180 # Die Dauer in Sekunden

# Hier wird nun jede Sekunde die Restzeit berechnet und ausgegeben
dauer.times {|x| sleep 1; puts ChronicDuration.output(dauer – x)}

# Ausgabe
3 mins
2 mins 59 secs
2 mins 58 secs
2 mins 57 secs
2 mins 56 secs
2 mins 55 secs
2 mins 54 secs
2 mins 53 secs
2 mins 52 secs

2 mins 2 secs
2 mins 1 sec
2 mins
1 min 59 secs
1 min 58 secs

1 min 2 secs
1 min 1 sec
1 min
59 secs
58 secs

3 secs
2 secs
1 sec
[/ruby]

Wenn Anfangs- und Zielzeit verwendet werden sollen, müssen wir erst die Countdown-Zeit berechnen:

[ruby]
# Die benötigten Bibliotheken
require ‚rubygems‘
require ‚chronic_duration‘
require ‚time‘

# Anfangs- und Zieldatum setzen und die Differenz berechnen
anfangsDatum = Time.now
=> Thu Sep 09 10:13:23 +0200 2010

zielDatum = Time.parse ‚2010-09-10 08:02:00 +0100‘
=> Fri Sep 10 09:02:00 +0200 2010

countdownZeit = (zielDatum – anfangsDatum).to_i # Ergebnis auf volle Sekunden gerundet
=> 82116

# Hier wird nun jede Sekunde die Restzeit berechnet und ausgegeben
countdownZeit.times {|x| sleep 1; puts ChronicDuration.output(countdownZeit – x)}

# Ausgabe
22 hrs 48 mins 36 secs
22 hrs 48 mins 35 secs
22 hrs 48 mins 34 secs
22 hrs 48 mins 33 secs
22 hrs 48 mins 32 secs

[/ruby]

Scripttip: Doppelte Arrayschlüssel zusammenfassen

Im heutigen Scripttip möchten wir euch zeigen, wie doppelte Schlüssel in einem mehrdimensionalen Array zusammengeasst werden können.

In diesem Beispiel werden die Werte über einen join zusammengefasst, aber dies lässt sich einfach an die eigenen Bedürfnisse anpassen.

[ruby]
doppelteSchluesselArray = [[:b, ‚B1‘], [:d, ‚D2‘], [:a, ‚A1‘], [:a, ‚A2‘], [:a, ‚A3‘], [:d, ‚D1‘], [:c, ‚C1‘]]
Hash[doppelteSchluesselArray.group_by(&:first).map {|k,v| [k,v.map(&:last).join(‚, ‚)]}]
=> {:d=>"D2, D1", :a=>"A1, A2, A3", :b=>"B1", :c=>"C1"}
[/ruby]

Scripttip: Mehr Informationen im Bash-Prompt

Welche Ruby-Version verwende ich gerade und in welchem Git-Branch arbeite ich momentan…? Um nicht jedes mal „–version“ und mehr aufzurufen um an diese Information zu kommen, kann man einfach sein Bash-Prompt erweitern. So sind die aktuellen Daten immer präsent und kann u.U. auch Fehler vermeiden.

Um die entsprechenden Details im Bash-Prompt anzuzeigen kann folgende Ergänzung in der .bashrc vorgenommen werden. (In diesem Beispiel gehe ich davon aus, dass rvm zur Verwaltung der Ruby-Version eingesetzt wird.)

[bash]
# In dieser Funktion ermitteln wir den aktuellen Git-Branch in dem wir uns befinden
function find_git_branch {
git branch –no-color 2> /dev/null | sed -e ‚/^[^*]/d‘ -e ’s/* (.*)/[1] /‘
}

rvm system

# Hier wird die aktuelle Ruby-Version ermittelt
function get_rvm_ruby_version(){
RUBY_INFO=`rvm-prompt`
PROMPT_STR=""
if [ -n "$RUBY_INFO" ]; then
PROMPT_STR="[$RUBY_INFO]"
fi
echo $PROMPT_STR
}

# Diese Funktion erweitert den Prompt mit den Daten aus den vorherigen Funktionen
function prompt_func(){
export PS1="[e]0;wa]n[e[32m]u@h [\033[1;36m]$(get_rvm_ruby_version) [\033[0;34m]$(find_git_branch) [e[33m]w[ e[0m]n$ "
}

PROMPT_COMMAND=prompt_func
[/bash]

Nachdem die .bashrc um diese Funtionen ergänzt wurden findet man alle Information in seinem neuen Prompt:
benutzer@host [ruby language=“-1.8.7-p248″][/ruby] [master] ~/mein/pfad/im/git/projekt

Wenn keine Ruby-Version aktiviert ist oder man sich nicht in einem Git-Verzeichnis befindet, werden die entsprechenden Stellen im Prompt weggelassen.

Scripttip: Herausfinden ob ein Datum in einen bestimmen Zeitraum fällt

Häufig ist es nötig herauszufinden ob ein Datum oder eine Uhrzeit in einen bestimmten Zeitraum fällt.
In diesem Scripttip zeigen wir euch wie dies ganz einfach mit Ruby geprüft werden kann.

[ruby]
# Die nötigen Bibliothek einbinden
require ‚time‘

# Hier erstellen wir das zu prüfende Datum
pruef_datum = Time.parse ‚2010-09-06 08:00:00 +0100‘
# => Mon Sep 08 09:00:00 +0200 2010

# Das Anfangsdatum für den zu überprüfenden Zeitraum
anfangs_datum = Time.parse ‚2010-09-01 00:00:00 +0100‘
# => Wed Sep 01 01:00:00 +0200 2010

# Das Enddatum für den zu überprüfenden Zeitraum
end_datum = Time.parse ‚2010-09-10 00:00:00 +0100‘
# => Fri Sep 10 01:00:00 +0200 2010

# Nun können wir mittels "between?" abfragen ob das Prüfdatum in unserem Zeitraum befindet
pruef_datum.between? anfangs_datum,end_datum
# => true
[/ruby]

Scripttip: Herausfinden ob ein Wert numerisch ist

In unserem heutigen Scripttip möchten wir euch zeigen wie man herausfinden kann, ob der Wert einer Variable numerisch ist.

Um festzustellen ob eine Variable einen numerischen Wert besitzt, können folgende Hilfsmethoden eingesetzt werden:

Prüfen ob es ein Integer-Wert ist:

[ruby]
meine_variable = "1234"

def meine_variable.ist_der_wert_ein_int?()
self.to_i.to_s == self
end

meine_variable.ist_der_wert_ein_int?
# => true
[/ruby]

Prüfen ob es Float-Wert ist:

[ruby]
meine_variable = "1234"

def meine_variable.ist_der_wert_ein_float?()
self.to_f.to_s == self
end

meine_variable.ist_der_wert_ein_float?
# => true
[/ruby]

Screencast: Resourcen vererben

Vererbte Resourcen können RESTful Controller erheblich vereinfachen, indem Standard-Actions eingesetzt werden. Ryan zeigt diese Woche wie das funktioniert.

 

Download:

Download(15.1 MB, 9:15)
Alternativer Download für iPod & Apple TV(14.4 MB, 9:15)

 

Resourcen:

 

Quellcode:

[ruby]
# Gemfile
gem ‚inherited_resources‘
gem ‚has_scope‘

# products_controller.rb
class ProductsController < InheritedResources::Base
respond_to :html, :xml
has_scope :limit, :default => 8

def create
create! { products_path }
end
end

# reviews_controller.rb
class ReviewsController < InheritedResources::Base
belongs_to :product
actions :index, :new, :create
has_scope :rating

def create
create! { collection_url }
end
end

# models/review.rb
scope :rating, proc { |rating| where(:rating => rating) }
[/ruby]

[text]
# config/locales/en.yml
en:
flash:
actions:
create:
notice: "Your {{resource_name}} has been created!"
[/text]