Screencast: Etwas zu Open-Source beitragen

Open-Source Projekte leben vom Beitrag von Freiwilligen. Github vereinfacht die Möglichkeit einen Teil, seien es auch nur kleine Verbesserungen, zur Verfügung zu stellen. An dem Beispiel von VCR zeigt Ryan diese Woche wie es funktioniert.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

bash

[bash]
git clone git@github.com:ryanb/vcr.git
cd vcr
git branch -r
bundle install
bundle exec rake
git submodule init
git submodule update
git status
git checkout .
git checkout -b readme-contributing-link
git diff
git commit -a -m "adding contributing link to readme"
git push origin readme-contributing-link
[/bash]

Gemfile

[ruby]
gem ‚rb-fsevent‘, ‚0.9.0.pre4‘
[/ruby]

Screencast: Spree – Einstieg in Ecommerce mit Rails

Spree ist eine open-source e-Commerce-Lösung auf Basis von Rails und wurde von Sean Schofield entwickelt. Inzwischen wird es von einer Community gepflegt ist aktuell die meistgenutzte Shop-Lösung im Rails-Umfeld. Ryan bietet diese Woche einen Einstieg in das Framework.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

bash

[bash]
brew install imagemagick
rails new store
bundle
rails g spree:site
rake db:bootstrap
[/bash]

Gemfile

[ruby]
gem ’spree‘, ‚0.70.1‘
gem ’spree_blue_theme‘, :git => ‚git://github.com/spree/spree_blue_theme.git‘
[/ruby]

config/initializers/spree_config.rb

[ruby]
Spree::Config.set(logo: "store/rails.png")
[/ruby]

overrides/logo.rb

[ruby]
Deface::Override.new(:virtual_path => "layouts/spree_application",
:name => "logo",
:replace_contents => "#logo",
:text => "Store")
[/ruby]

app/assets/stylesheets/store/all.css

[css]
/*
*= require store/screen
* …
*/
[/css]

app/assets/stylesheets/store/layout.css.scss

[css]
#logo {
font-size: 32px;
color: #FFF;
}
[/css]

Screencast: Mercury Online Editor

Mercury ist ein auf HTML5 basierender Web-Editor mit dem Inhalte direkt im Browser bearbeitet werden können. In dem folgenden Screencast zeigt Ryan wie es in eigenen Applikationen eingebunden und benutzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

Gemfile

[ruby]
gem ‚mercury-rails‘, git: ‚https://github.com/jejacks0n/mercury.git‘, ref: ‚a2b16bcdc9‘
[/ruby]

bash

[bash]
bundle
rails g mercury:install
rake mercury_engine:install:migrations
rake db:migrate
[/bash]

pages/show.html.erb

[html]
<h1><span id="page_name" class="mercury-region" data-type="editable"><%= raw @page.name %></span></h1>

<div id="page_content" class="mercury-region" data-type="editable">
<%= raw @page.content %>
</div>
<p><%= link_to "Edit Page", "/editor" + request.path, id: "edit_link", data: {save_url: mercury_update_page_path(@page)} %></p>
[/html]

config/routes.rb

[ruby]
resources :pages do
member { post :mercury_update }
end
[/ruby]

pages_controller.rb

[ruby]
def mercury_update
page = Page.find(params[:id])
page.name = params[:content][:page_name][:value]
page.content = params[:content][:page_content][:value]
page.save!
render text: ""
end
[/ruby]

app/assets/javascripts/mercury.js

[javascript]
$(window).bind(‚mercury:ready‘, function() {
var link = $(‚#mercury_iframe‘).contents().find(‚#edit_link‘);
Mercury.saveURL = link.data(’save-url‘);
link.hide();
});

$(window).bind(‚mercury:saved‘, function() {
window.location = window.location.href.replace(//editor//i, ‚/‘);
});
[/javascript]

views/layouts/mercury.html.erb

[html]

saveStyle: ‚form‘,

[/html]

Screencast: Virtuelle Maschinen mit Vagrant

Virtuelle Maschinen sind sehr praktisch um Umgebungen für Entwicklung und Tests aufzubauen. Mit Vagrant besteht die Möglichkeit diese automatisiert zu provisionieren und auf Wunsch so produktionsnah wie nötig aufzusetzen. Weiterhin können mit Virtuellen Maschinen eine gemeinsame Umgebung eingerichtet werden, damit alle Projektmitglieder auf der gleichen Umgebung arbeiten. Dadurch kann ggf. Fehler beim Übergang auf eine produktive Umgebung gemindert werden. Ryan zeigt in seinem Screencast wie Vagrant zum Aufsetzen von Virtuellen Maschinen auf Basis von Virtual-Box eingesetzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

Vagrantfile

[ruby]
config.vm.forward_port "rails", 3000, 3000
[/ruby]

Gemfile

[ruby]
gem ‚therubyracer‘
[/ruby]

bash

[bash]
# setup vagrant
gem install vagrant
vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
rails new todo
cd todo
vagrant init lucid32
mate Vagrantfile
vagrant up
vagrant ssh

# inside virtual machine
whoami
cd /vagrant
ruby -v
sudo apt-get update
sudo apt-get install build-essential zlib1g-dev curl git-core sqlite3 libsqlite3-dev

# install rbenv and Ruby 1.9.2
git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
echo ‚export PATH="$HOME/.rbenv/bin:$PATH"‘ >> ~/.bash_profile
echo ‚eval "$(rbenv init -)"‘ >> ~/.bash_profile
source .bash_profile
git clone git://github.com/sstephenson/ruby-build.git
cd ruby-build/
sudo ./install.sh
rbenv install 1.9.2-p290

# get Rails running
cd /vagrant
gem install bundler
rbenv rehash
bundle
bundle exec rails s

# vagrant commands
vagrant reload
vagrant status
vagrant suspend
vagrant resume
vagrant halt
vagrant up
vagrant package
vagrant destroy
[/bash]

Screencast: Administrationsfläche über Active Admin

Fast jede Applikation benötigt eine Administrationsfläche, mit der Werte angepasst und Texte verwaltet werden können. Active Admin bringt diese Möglichkeit der Verwaltung für Rails Applikationen mit und sieht obendrein auch nett aus. Ryan zeigt in diesem Screencast wie es installiert und benutzt wird.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

bash

[bash]
bundle rails g active_admin:install rake db:migrate rails g active_admin:resource product
[/bash]

Gemfile

[ruby]
gem ‚activeadmin‘
[/ruby]

app/admin/products.rb

[ruby]
ActiveAdmin.register Product do scope :unreleased index do column :name column :category column "Release Date", :released_at column :price, :sortable => :price do |product| div :class => "price" do number_to_currency product.price end end default_actions end end
[/ruby]

app/admin/dashboards.rb

[ruby]
ActiveAdmin::Dashboards.build do section "Recent Products" do table_for Product.order("released_at desc").limit(5) do column :name do |product| link_to product.name, [:admin, product] end column :released_at end strong { link_to "View All Products", admin_products_path } end end
[/ruby]

app/assets/stylesheets/application.css.scss

[css]
@import "products";
[/css]

config/initializers/active_admin.rb

[ruby]
config.site_title = "Ryan’s Store"
[/ruby]

Screencast: Authentifizierung mit sorcery

sorcery ist ein modular aufgebautes Authetifizierungs-System für Rails 3.0/3.1. In diesem Screencast zeigt Ryan wie es eingesetzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
mp4
webm
ogg

 

Resourcen:

bash

[bash]
bundle
rake sorcery:bootstrap
rails g sorcery_migration core remember_me
rails g model user –skip-migration
rake db:migrate
rails g controller users new
rails g controller sessions new
[/bash]

Gemfile

[ruby]
gem ’sorcery‘
[/ruby]

config/initializers/sorcery.rb

[ruby]
Rails.application.config.sorcery.submodules = [:remember_me]

# . . .

user.username_attribute_name = :email
[/ruby]

models/user.rb

[ruby]
class User < ActiveRecord::Base
authenticates_with_sorcery!

attr_accessible :email, :password, :password_confirmation

validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email
end
[/ruby]

users_controller.rb

[ruby]
def new
@user = User.new
end

def create
@user = User.new(params[:user])
if @user.save
redirect_to root_url, :notice => "Signed up!"
else
render :new
end
end
[/ruby]

views/users/new.html.erb

[html]
<%= form_for @user do |f| %>
<% if @user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in @user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
[/html]

sessions_controller.rb

[ruby]
def create
user = login(params[:email], params[:password], params[:remember_me])
if user
redirect_back_or_to root_url, :notice => "Logged in!"
else
flash.now.alert = "Email or password was invalid"
render :new
end
end

def destroy
logout
redirect_to root_url, :notice => "Logged out!"
end
[/ruby]

views/sessions/new.html.erb

[html]
<%= form_tag sessions_path do %>
<div class="field">
<%= label_tag :email %>
<%= text_field_tag :email, params[:email] %>
</div>
<div class="field">
<%= label_tag :password %>
<%= password_field_tag :password %>
</div>
<div class="field">
<%= check_box_tag :remember_me, 1, params[:remember_me] %>
<%= label_tag :remember_me %>
</div>
<div class="actions"><%= submit_tag "Log in" %></div>
<% end %>
[/html]

config/routes.rb

[ruby]
get "logout" => "sessions#destroy", :as => "logout"
get "login" => "sessions#new", :as => "login"
get "signup" => "users#new", :as => "signup"
resources :users
resources :sessions
[/ruby]

home_controller.rb

[ruby]
before_filter :require_login, :only => :secret
[/ruby]

application_controller.rb

[ruby]
def not_authenticated
redirect_to login_url, :alert => "First login to access this page."
end
[/ruby]

application.html.erb

[html]
<% if current_user %>
Logged in as <%= current_user.email %>.
<%= link_to "Log out", logout_path %>
<% else %>
<%= link_to "Sign up", signup_path %> or
<%= link_to "log in", login_path %>.
<% end %>
[/html]

Screencast: Vererbung von Templates

Teile von Templates wieder zu verwenden wurde bisher größtenteils über partials verwirklicht. In Rails 3.1 wird es möglich sein Templates zu vererben. So können Teile von Views auf allgemein gültige zurückgreifen und darstellen. Ryan zeigt diese Woche wie in einer Applikation ein Template von allen Views genutzt und wie es im Zusamenhang mit Subdomains eingesetzt werden kann.

 

Downloads in verschiedenen Formaten:

source code
mp4
m4v
webm
ogv

 

Resourcen:

application_controller.rb

[ruby]
before_filter :subdomain_view_path

private

def subdomain_view_path
prepend_view_path "app/views/#{request.subdomain}_subdomain" if request.subdomain.present?
end
[/ruby]

views/layouts/application.html.erb

[html]
<%= render "side" %>
[/html]

views/application/_side.html.erb

[html]
<strong>Pages</strong>
<ul>
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Products", products_path %></li>
</ul>
[/html]

views/admin/base/_side.html.erb

[html]
<strong>Pages</strong>
<ul>
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Products", products_path %></li>
<li><%= link_to "Manage Products", admin_products_path %></li>
<li><%= link_to "Manage Categories", admin_categories_path %></li>
</ul>
[/html]

views/mobile_subdomain/products/index.html.erb

[html]
<h1>Mobile Version</h1>
[/html]

edit.html.erb

[html]
<%= controller.view_paths %>
[/html]

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: Undo mit Paper Trail

„Undo“ und „Redo“ Funktionen lassen sich sehr einfach mit gems wie zum Beispiel Paper Trails implementieren. In dieser Woche zeigt Ryan wie es eingesetzt werden kann.

div> 

Download:

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

 

Resourcen:

 

Quellcode:

[bash]
bundle
rails g paper_trail:install
rake db:migrate
rails g controller versions
[/bash]

[ruby]
# Gemfile
gem ‚paper_trail‘

# products_controller
def undo_link
view_context.link_to("undo", revert_version_path(@product.versions.scoped.last), :method => :post)
end

# routes.rb
post "versions/:id/revert" => "versions#revert", :as => "revert_version"

# versions_controller
def revert
@version = Version.find(params[:id])
if @version.reify
@version.reify.save!
else
@version.item.destroy
end
link_name = params[:redo] == "true" ? "undo" : "redo"
link = view_context.link_to(link_name, revert_version_path(@version.next, :redo => !params[:redo]), :method => :post)
redirect_to :back, :notice => "Undid #{@version.event}. #{link}"
end
[/ruby]