Screencast: Clientseitige Validierung von Formularen

Clientseitige Validierung, also die Überprüfung von eingegebenen Werten innerhalb des Webbrowsers, können dem Benutzer bereits bei der Eingabe über die Korrektheit der Daten informieren. Dies kann unter Umständen den einen oder anderen Korrigier-Zyklus ersparen. Wie dies innerhalb von Rails eingesetzt werden kann zeigt Ryan diese Woche anhand eines gems, welches die Entwicklung erleichtert.

 

Download:

Download(20.2 MB, 8:42)
Alternativer Download für iPod & Apple TV(19.3 MB, 8:42)

 

Resourcen:

 

Quellcode:

[bash]
bundle
rails g client_side_validations:install
[/bash]

[ruby]
# Gemfile
gem ‚client_side_validations‘

# models/user.rb
validates_uniqueness_of :username, :email
validates :email, :email_format => true

# lib/email_format_validator.rb
class EmailFormatValidator < ActiveModel::EachValidator
def validate_each(object, attribute, value)
unless value =~ /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i
object.errors.add(attribute, :email_format, options)
end
end
end

# config/application.rb
config.autoload_paths << "#{config.root}/lib"
[/ruby]

[html]
<!– users/_form.html.erb –>
<%= form_for @user, :validate => true do |f| %>

<!– layouts/application.html.erb –>
<%= javascript_include_tag :defaults, "rails.validations", "rails.validations.custom" %>
[/html]

[text]
# locals/en.yml
en:
errors:
messages:
email_format: "is not formatted properly"
[/text]

[javascript]
/* rails.validations.custom.js */
clientSideValidations.validators.local["email_format"] = function(element, options) {
if (!/^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i.test(element.val())) {
return options.message;
}
}
[/javascript]

Screencast: Daten-Bäume mit Ancestry verwenden

Ancestry ist ein gem über welches man auf einfache Weise Baumstrukturen in Rails (2+3) /Ruby-Applikationen einsetzen kann. Neben allen zu erwartenenden Funktionen wie zum Beispiel für Eltern, Kinder und Nachbar-Elementen, unterstützt Ancestry auch STI (Single Table Inheritance). Auch Funktionen zum Sortieren, Integretäts-Test und Rückwärtskombatibilität sind verfügbar.
Ryan zeigt in dieser Woche wie es in eingesetzt werden kann.

 

Download:

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

 

Resourcen:

 

Quellcode:

[bash]
bundle
rails g migration add_ancestry_to_messages ancestry:string
rake db:migrate
[/bash]

[ruby]
# Gemfile
gem ‚ancestry‘

# migration.rb
class AddAncestryToMessages < ActiveRecord::Migration
def self.up
add_column :messages, :ancestry, :string
add_index :messages, :ancestry
end

def self.down
remove_index :messages, :ancestry
remove_column :messages, :ancestry
end
end

# messages_controller.rb
def new
@message = Message.new(:parent_id => params[:parent_id])
end

# messages_helper.rb
def nested_messages(messages)
messages.map do |message, sub_messages|
render(message) + content_tag(:div, nested_messages(sub_messages), :class => "nested_messages")
end.join.html_safe
end
[/ruby]

[html]
<!– messages/index.html.erb –>
<%= nested_messages @messages.arrange(:order => :created_at) %>

<!– messages/show.html.erb –>
<%= nested_messages @message.subtree.arrange(:order => :created_at) %>

<!– messages/_form.html.erb –>
<%= f.hidden_field :parent_id %>

<!– messages/_message.html.erb –>
<%= link_to message.content, message %>

<%= link_to "Reply", new_message_path(:parent_id => message) %> |
[/html]

[css]
/* application.css */

.nested_messages {
margin-left: 30px;
}

.nested_messages .nested_messages .nested_messages .nested_messages {
margin-left: 0;
}
[/css]

Screencast: JavaScript mit Jasmine testen

Jasmine ist ein BDD-Testframework um JavaScript zu testen. Es ist für die Tests nicht auf DOM angewiesen und hat auch keine Abhängigkeiten zu anderen Frameworks. Ryan zeigt wie es in Kombination mit Rails eingesetzt werden kann.

 

Download:

Download(24.8 MB, 15:20)
Alternativer Download für iPod & Apple TV(25.3 MB, 15:20)

 

Resourcen:

 

Quellcode:

[bash]
bundle
rails g jasmine:install
rake jasmine
rake jasmine:ci
curl http://cloud.github.com/downloads/velesin/jasmine-jquery/jasmine-jquery-1.2.0.js > spec/javascripts/helpers/jasmine_jquery-1.2.0.js
[/bash]

[ruby]
# Gemfile
gem ‚jasmine‘, :group => [:development, :test]
[/ruby]

[javascript]
/* credit_card_spec.js */

describe("CreditCard", function() {
it("cleans number by removing spaces and dashes", function() {
expect(CreditCard.cleanNumber("123 4-5")).toEqual("12345");
});

it("validates based on mod 10", function() {
expect(CreditCard.validNumber("4111 1111-11111111")).toBeTruthy();
expect(CreditCard.validNumber("4111111111111121")).toBeFalsy();
});

it("validates when text field loses focus", function() {
loadFixtures("order_form.html");
$("#card_number").validateCreditCardNumber();
$("#card_number").val("123");
$("#card_number").blur();
expect($("#card_number_error")).toHaveText("Invalid credit card number.");
$("#card_number").val("4111 1111-11111111");
$("#card_number").blur();
expect($("#card_number_error")).toHaveText("");
});
});

/* credit_card.js */
var CreditCard = {
cleanNumber: function(number) {
return number.replace(/[- ]/g, "");
},

validNumber: function(number) {
var total = 0;
number = this.cleanNumber(number);
for (var i=number.length-1; i >= 0; i–) {
var n = parseInt(number[i]);
if ((i+number.length) % 2 == 0) {
n = n*2 > 9 ? n*2 – 9 : n*2;
}
total += n;
};
return total % 10 == 0;
}
};

(function($){
$.fn.validateCreditCardNumber = function() {
return this.each(function() {
$(this).blur(function() {
if (!CreditCard.validNumber(this.value)) {
$("#" + this.id + "_error").text("Invalid credit card number.");
} else {
$("#" + this.id + "_error").text("");
}
});
});
};
})(jQuery);

/* applicaiton.js */
$(function() {
$("#order_credit_card_number").validateCreditCardNumber();
});
[/javascript]

[html]
<!– orders/_form.html.erb –>
<%= f.text_field :credit_card_number %>
<span id="order_credit_card_number_error"></span>
[/html]

Screencast: Einfaches Messaging mit Faye

Faye ist ein einfach zu benutzendes messaging system, welches auf dem Bayeux Protokoll basiert. In diesem Screencast könnt ihr sehen wie es in Rails eingesetzt werden kann.

 

Download:

Download(17.9 MB, 13:42)
Alternativer Download für iPod & Apple TV(18.5 MB, 13:42)

 

Resourcen:

 

Quellcode:

[bash]
gem install faye
rackup faye.ru -s thin -E production
curl http://localhost:9292/faye -d ‚message={"channel":"/messages/new", "data":"hello"}‘
[/bash]

[ruby]
# config/application.rb
require "net/http"

# config/initializers/faye_token.rb
FAYE_TOKEN = "anything"

# application_helper.rb
def broadcast(channel, &block)
message = {:channel => channel, :data => capture(&block), :ext => {:auth_token => FAYE_TOKEN}}
uri = URI.parse("http://localhost:9292/faye")
Net::HTTP.post_form(uri, :message => message.to_json)
end

# faye.ru
require ‚faye‘
require File.expand_path(‚../config/initializers/faye_token.rb‘, __FILE__)

class ServerAuth
def incoming(message, callback)
if message[‚channel‘] !~ %r{^/meta/}
if message[‚ext‘][‚auth_token‘] != FAYE_TOKEN
message[‚error‘] = ‚Invalid authentication token‘
end
end
callback.call(message)
end
end

faye_server = Faye::RackAdapter.new(:mount => ‚/faye‘, :timeout => 45)
faye_server.add_extension(ServerAuth.new)
run faye_server
[/ruby]

[html]
<% broadcast "/messages/new" do %>
$("#chat").append("<%= escape_javascript render(@message) %>");
<% end %>
$("#new_message")[0].reset();
[/html]

[javascript]
/* application.js */
$(function() {
var faye = new Faye.Client(‚http://localhost:9292/faye‘);
faye.subscribe("/messages/new", function(data) {
eval(data);
});
});
[/javascript]

Rails 3.0.6 Sicherheitsupdate veröffentlicht

Rails ist in der Version 3.0.6 als Sicherheitsupdate erschienen. Das geschlossene Sicherheitsleck betrifft einen möglichen Angriff über XSS. Dabei kann bei der Verwendung von auto_link Fremdcode eingeschleust werden.

Wenn folgendes in der View verwendet wird:

<%= auto_link(params[:content]) %>

Kann unter bestimmten Vorraussetzungen über „content“ unerwünschter JavaScript-Code eingeschleust werden.

Um sich gegen diese Lücke zu schützen, ….

  • … auf Rails 3.0.6 aktualisiert werden
  • … der folgende Patch eingespielt werden: Patch
  • … wenn Update oder das Patchen nicht möglich ist, kann händisch das Problem umgangen werden
    • <%= sanitize(auto_link(params[:content])) %>
    • bei vertrauenswürdigen Quellen
      <%= raw(auto_link(params[:content])) %>

Weitere Details zu dem Release findet ihr unter folgendem Link: –> Link