Ruby on Rails 2.3.8

Wie es aussieht wurde Rails 2.3.7 zu schnell herausgegeben und im Nachhinein hat sich herausgestellt, dass der letzte Patch ein paar Probleme macht. Daher ist heute eine neue stabile Version veröffentlicht worden.

Jeremy schreibt im Rails-Blog, dass die Veröffentlichung wohl zu hastig war und er entschuldigt sich für evtl. Unannehmlichkeiten.
Trotz des Release-Marathons an diesem Wochenende ist es gut, dass das Core-Team schnell auf Probleme reagiert und somit eine stabiliere + sichere Software zur Verfügung stellt.

Screencast: Fortgeschrittene Abfragen in Rails 3

In dieser Woche behandelt Ryan fortgeschrittene Abfragemöglichkeiten in Rails 3. Er zeigt wie „named scopes“ eingesetzt werden können und es gibt dabei auch eine Einführung in Arel. Arel wird mit Rails 3 eingeführt und wird die Erstellung von DB-Queries vereinfachen und verbessern.

 

Download:

Download(33.9 MB, 9:26)
Alternativer Downloadfür iPod & Apple TV(47 MB, 9:26)

 

Resourcen:

 

Quellcode:

[ruby]
# rails console
Product.cheap.to_sql
(Category.joins(:products) & Product.cheap).to_sql
Category.with_cheap_products.to_sql
p = Product.discontinued.build
p.discontinued
t = Product.arel_table
t[:price].eq(2.99)
t[:name].matches("%catan").to_sql
Product.where(t[:price].eq(2.99).or(t[:name].matches("%catan")))

# models/product.rb
scope :discontinued, where(:discontinued => true)

def self.cheaper_than(price)
where("products.price < ?", price)
end

scope :cheap, cheaper_than(5)

# models/category.rb
scope :with_cheap_products, joins(:products) & Product.cheap
[/ruby]

Ruby on Rails 2.3.7 erschienen

Kurz nachdem Rails 2.3.6 veröffentlicht wurde, hat Nathan Weizenbaum angefangen HAML anzupassen. Dabei sind ihm ein paar Bugs aufgefallen die Sicherheitsrelevant werden könnten. Daher wurde entschieden ein weiteres Release zu veröffentlichen, um diese Lücke zu schließen.

Wenn das rails_xss  Plugin (http://github.com/rails/rails_xss#readme) verwendet wird, sollte sowohl die Railsumgebung und das Plugin aktualisiert werden.

Die Änderungen und Anpassungen können bei Git-Hub nachgelesen werden: http://github.com/rails/rails/compare/v2.3.6…v2.3.7

Ruby on Rails 2.3.6 erschienen

Die Zweier Version von Ruby on Rails hat ein weiteres Update erfahren und soeben wurde Version 2.3.6 veröffentlicht. In den letzten sechs Monaten sind Bugfixes, einige neue Features und Vorbereitungen zu Rails 3 eingeflossen. Es wurden weitere Teile als veraltet/deprecated markiert, damit Entwickler Ihre Applikationen für das nächste große Release vorbereiten können. Jeremy Camper schreibt, dass bestehende Rails-Applikationen die keine Warnungen über veraltete Kompontenten werfen, einen unproblematischen Übergang zu Rails 3 erwarten können.

Folgende Änderungen sind in das Release geflossen:

Action Pack

Active Record

Active Support

  • Upgrade i18n von 1.3.3 zu 1.3.7.
  • Upgrade TZInfo von 0.3.12 zu 0.3.16.
  • Multibyte: Geschwindigkeitesverbeserung.
  • JSON: Es kommt nun YAJL, wenn vorhanden, beim decodieren von JSON  zum Einsatzt.  gem install yajl-ruby
  • Testing: Die Methoden assert_blank und assert_present sind hinzugekomen. Weitere Details: http://github.com/rails/rails/commit/4b08679ba9627884d531cf59a9bb2fd1d2c86d62.
  • Core: Rückportierung von Object#singleton_class von Ruby 1.8.8,
  • Object#metaclass ist nun depracted.
  • Core: Object#presence ist hinzugekommen und gibt, wenn es Verfügbar ist ( #present?), das Objekt zurück. Wenn das Objekt nicht verfügbar ist wird nil zurückgeben. Zum Beispiel: region = params[:state].presence || params[:country].presence || 'US'
  • Core:  Enumerable#exclude? ist als Gegenstück zu include? hinzugekommen.
  • Core: Array#rand wurde zu Array#random_element umbenannt umd Namensüberschneidung mit  Kernel#rand zu vermeiden.
  • Core: Date# und Time#last_(month|year) wurden zu #prev_(month|year) umbenannt, um die Unterstützung in Ruby 1.9 zu gewährleisten.

Active Resource

  • JSON: setActiveResource::Base.include_root_in_json = true zur Serialisierung von Modelnamen, anstatt einfacher Hash-Attributen. Der Standardwert ist false

Action Mailer

  • Upgrade  von TMail von 1.2.3 auf 1.2.7.

Railties

  • Warnungen über veraltete Komponenten in RubyGems 1.3.6.

Die vollständige Liste der Änderungen ist im Commit Log einsehbar: http://github.com/rails/rails/compare/v2.3.5…v2.3.6

Update von Rails 2 nach Rails 3

Um eine Rails 2 Applikation nach Rails 3 zu migrieren oder aktualisieren sind ein paar Dinge zu beachten. Rizwan Reza von Engine Yard hat hierzu eine ausführliche Beschreibung zusammengestellt und einen entsprechenden Screencast dazu erstellt.

Rizwan beschreibt alle nötigen Schritte um auf die neue Version umzusteigen. Nebenbei erfährt der Leser und Zuschauer mehr über die Neuerungen und wie man mit diesen umgeht.

Link zum Artikel: http://railsdispatch.com/posts/upgrading-a-rails-2-app-to-rails-3

 

Der Rails 3 Upgrade Screencast zu dem Artikel:

 

Screencast: A/B Tests mit A/Bingo

A/B Tests oder Split-Tests werden verwendet um die Akzeptanz einer Applikation in zwei verschiedenen Ausprägungen zu prüfen. In dem heutigen Screencast wird dazu A/Bingo vorgestellt und vorgeführt wie es dazu verwendet werden kann.

 

Download:

Download(35.1 MB, 11:04)
Alternativer Downloadfür iPod & Apple TV(27.6 MB, 11:04)

 

Resourcen:

 

Quellcode:

[bash]
script/plugin install git://git.bingocardcreator.com/abingo.git
script/generate abingo_migration
rake db:migrate
script/generate controller abingo_dashboard
script/plugin install –force git://github.com/ryanb/abingo.git
[/bash]

[ruby]
# users_controller.rb
bingo! "signup_intro"
bingo! "signup_title"
# or
bingo! "signup"

# application_controller.rb
before_filter :set_abingo_identity

private

def set_abingo_identity
if request.user_agent =~ /b(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg)b/i
Abingo.identity = "robot"
elsif current_user
Abingo.identity = current_user.id
else
session[:abingo_identity] ||= rand(10 ** 10)
Abingo.identity = session[:abingo_identity]
end
end

# abingo_dashboard_controller.rb
class AbingoDashboardController < ApplicationController
# TODO add some authorization
include Abingo::Controller::Dashboard
end

# routes.rb
map.abingo_dashboard "/abingo/:action/:id", :controller=> :abingo_dashboard
[/ruby]

[html]
<% ab_test("signup_title", ["Sign up", "Registration", "Free Sign up"], :conversion => "signup") do |signup_title| %>
<% title "Free Sign up" %>
<% end %>

<% if ab_test "signup_intro", nil, :conversion => "signup" %>
<p>…</p>
<% end %>
[/html]

RubyGems 1.3.7 veröffentlicht

Das Paketveraltungswerkzeug RubyGem für Ruby ist in der Version 1.3.7 erschienen. Dieses Update bringt einige Neuerungen und Bugfixes mit sich.
Um das eigene System zu aktualisieren muss eine 1.3’er Version bereits installiert sein, da die Versionen 1.1 und 1.2 das Update mit “Nothing to update” abbrechen.

Das Update kann folgendermaßen installiert werden:

[bash]
gem update –system
# ggf. sind Administrationsrechte (root) erforderlich, dann sollte das Update über sudo o. Ä. ausgeführt werden:
sudo gem update –system
[/bash]

Wenn rvm benutzt wird, sollte die Installation nicht als root erfolgen.

Falls eine ältere Version von RubyGems aktualisiert werden soll, muss diese erst auf eine kompatible Version gebracht werden:

[bash]
# Auch hier müssen die Befehle ggf. als root ausgeführt werden. Dazu muss lediglich sudo vor das jeweilge Kommando gesetzt werden
gem install rubygems-update
update_rubygems
[/bash]

Falls RubyGems noch nicht vorhanden ist bzw. neu installiert werden soll, kann dies folgendwermaßen erfolgen:

  1. RubyGems runterladen unter: rubyforge.org/frs/?group_id=126
  2. Das Archiv entpacken und mit „cd“ in das entpackte Verzeichnis navigieren
  3. Dann die Installation mit „ruby setup.rb“ ausführen. (Auch hier: ggf. als root)

Weiter Details können vor der Installation mit folgendem Befehl angezeigt werden:

[bash]
ruby setup.rb –help
[/bash]

Eine der Neuerungen in dieser Version ist, dass nun rubygems.org nun als Standard-Adresse für die Paketsuche + Installation verwendet wird. gems.rubyforge.org wird noch auf unbestimmte Zeit funktionieren.

 

Neue Features:

  • „gem install“ und „gem fetch“ zeigen nun alternative Platformen an, wenn keine passende gefunden wird
  • „gem contents“ –prefix ist nun standardmäßig spezifiziert in –help
  • „gem fetch“ kann nun wieder ätere Versionen holen
  • „gem query“ und Ähnliche zeigen nun eine Liste von Platformen bei der Ausgabe an
  • „gem server“ erlaubt nun mehrere gem-Installations-Verzeichnise anzugeben
  • „gem unpack“ entpackt wieder gems
  • „gem unpack“ entpackt nun auch entfernte gems (z.B. noch nicht installierte)
  • „–user-install“ wird nicht mehr als Standard bei der Installation von gems gesetzt
  • RubyGems unterstützt nun IronRuby als Zielplatform

Neben den Neuerungen hat diese Version auch ein paar Bugfixes erfahren.

Hilfe und weitere Informationen können nach der Installation mit folgendem Befehl auf der Konsole abgefragt werden:

[bash]
ri Gem
[/bash]

Screencast: Kalender-Funktion

Es gibt verschiedene Möglichkeiten um einem Benutzer ein Datum auswählen zu lassen oder einen Kalender zu präsentieren. In dieser Woche zeigt Ryan einige Beispiele und Lösungen dafür.

 

Download:

Download(15.6 MB, 9:50)
Alternativer Downloadfür iPod & Apple TV(14.9 MB, 9:50)

 

Resourcen:

 

Quellcode:

[bash]
script/plugin install git://github.com/p8/table_builder.git
[/bash]

[ruby]
# articles_controller.rb
def index
@articles = Article.find(:all)
@date = params[:month] ? Date.parse(params[:month]) : Date.today
endv
[/ruby]

[html]
<!– layouts/application.html.erb –>
<%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/redmond/jquery-ui.css", "application" %>
<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js", "application" %>

<!– articles/index.html.erb –>
<div id="calendar">
<h2 id="month">
<%= link_to "<", :month => (@date.beginning_of_month-1).strftime("%Y-%m") %>
<%=h @date.strftime("%B %Y") %>
<%= link_to ">", :month => (@date.end_of_month+1).strftime("%Y-%m") %>
</h2>
<% calendar_for @articles, :year => @date.year, :month => @date.month do |calendar| %>
<%= calendar.head(‚Sunday‘, ‚Monday‘, ‚Tuesday‘, ‚Wednesday‘, ‚Thursday‘, ‚Friday‘, ‚Saturday‘) %>
<% calendar.day(:day_method => :published_on) do |date, articles| %>
<%= date.day %>
<ul>
<% for article in articles %>
<li><%= link_to h(article.name), article %></li>
<% end %>
</ul>
<% end %>
<% end %>
</div>

<!– articles/_form.html.erb –>
<%= f.text_field :published_on %>
[/html]

[javascript]
// application.js
$(function() {
$("#article_published_on").datepicker();
});
[/javascript]

[css]
#calendar table {
border-collapse: collapse;
width: 100%;
}

#calendar td,
#calendar th {
font-family: "Lucida Grande",arial,helvetica,sans-serif;
font-size: 10px;
padding: 6px;
border: 1px solid #999;
}

#calendar th {
background: #DDD;
color: #666;
text-align: center;
width: 14.2857142857143%;
}

#calendar td {
background: #FFF;
color: #777;
height: 80px;
vertical-align: top;
font-size: 16px;
}

#calendar .notmonth {
color: #CCC;
}

#calendar #month {
margin: 0;
padding-top: 10px;
padding-bottom: 10px;
text-align: center;
}

#calendar #month a, #calendar #month a:hover {
text-decoration: none;
padding: 0 10px;
color: #999;
}

#calendar .today {
background-color: #D7F2FF;
}

#calendar ul {
margin: 0;
margin-top: 5px;
padding: 0;
list-style: none;
}

#calendar li {
margin: 0;
padding: 0;
font-size: 11px;
text-align: center;
}
[/css]

Screencast: Refactoring und Dynamic Delegator

Code Refactoring ist der Prozess bei dem ein Programm modifiziert (optimiert, verbessert) wird ohne sein Verhalten nach aussen zu verändern. Diese Woche zeigt Ryan wie Refactoring eingesetzt werden kann und wie man Dynamic Delegator in Active Recors nutzt.

 

Download:

Download (11.2 MB, 7:58)
Alternativer Download für iPod & Apple TV (10.9 MB, 7:58)

 

Resourcen:

 

Quellcode:

[ruby]
# rails console
Product.search({}).class
Object.instance_methods
BasicObject.instance_methods

# products_controller.rb
@products = Product.search(params)

# models/product.rb
def self.search(params)
products = scope_builder
products.where("name like ?", "%" + params[:name] + "%") if params[:name]
products.where("price >= ?", params[:price_gt]) if params[:price_gt]
products.where("price <= ?", params[:price_lt]) if params[:price_lt]
products
end

def self.scope_builder
DynamicDelegator.new(scoped)
end

# lib/dynamic_delegator.rb
class DynamicDelegator < BasicObject
def initialize(target)
@target = target
end

def method_missing(*args, &block)
result = @target.send(*args, &block)
@target = result if result.kind_of? @target.class
result
end
end
[/ruby]