Screencast: Datenexport nach Excel oder CSV

Für Datenexporte wird häufig CSV und/oder Excel eingesetzt. In Rails ist es relativ einfach diese Formate zur Verfügung zu stellen. Wie dies funktioniert, welche Optionen zur Verfügung stehen und wie ein Excel-Export in verschiedenen Formaten aussehen kann, zeigt Ryan in diesem Screencast.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

config/application.rb

[ruby]
require ‚csv‘
[/ruby]

products_controller.rb

[ruby]
def index
@products = Product.order(:name)
respond_to do |format|
format.html
format.csv { send_data @products.to_csv }
format.xls # { send_data @products.to_csv(col_sep: "t") }
end
end
[/ruby]

models/product.rb

[ruby]
def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |product|
csv << product.attributes.values_at(*column_names)
end
end
end
[/ruby]

config/initializers/mime_types.rb

[ruby]
Mime::Type.register "application/xls", :xls
[/ruby]

views/products/index.xls.erb

[html]
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table>
<Row>
<Cell><Data ss:Type="String">ID</Data></Cell>
<Cell><Data ss:Type="String">Name</Data></Cell>
<Cell><Data ss:Type="String">Release Date</Data></Cell>
<Cell><Data ss:Type="String">Price</Data></Cell>
</Row>
<% @products.each do |product| %>
<Row>
<Cell><Data ss:Type="Number"><%= product.id %></Data></Cell>
<Cell><Data ss:Type="String"><%= product.name %></Data></Cell>
<Cell><Data ss:Type="String"><%= product.released_on %></Data></Cell>
<Cell><Data ss:Type="Number"><%= product.price %></Data></Cell>
</Row>
<% end %>
</Table>
</Worksheet>
</Workbook>
[/html]

Screencast: Mehrseitige Formulare mit Wicked

Mehrseitige Formulare sind nicht immer einfach zu erstellen. Wicket ist ein Plugin das genau diese Nische bedient und die Erstellung vereinfacht. Mit Wicket lassen sich Controller in eine Serie von Schritten verwandeln um seitenweise Daten zu erfassen.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

terminal

[bash]
rails g controller user_steps
[/bash]

user_steps_controller.rb

[ruby]
class UserStepsController < ApplicationController
include Wicked::Wizard
steps :personal, :social

def show
@user = current_user
render_wizard
end

def update
@user = current_user
@user.attributes = params[:user]
render_wizard @user
end

private

def redirect_to_finish_wizard
redirect_to root_url, notice: "Thank you for signing up."
end
end
[/ruby]

user_steps/personal.html.erb

[html]
<h1>Tell us a little about yourself.</h1>

<%= render layout: ‚form‘ do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :date_of_birth %><br />
<%= f.date_select :date_of_birth, start_year: 1900, end_year: Date.today.year, include_blank: true %>
</div>
<div class="field">
<%= f.label :bio %><br />
<%= f.text_area :bio, rows: 5 %>
</div>
<% end %>
[/html]

user_steps/social.html.erb

[html]
<h1>Where can we find you?</h1>

<%= render layout: ‚form‘ do |f| %>
<div class="field">
<%= f.label :twitter_username %><br />
<%= f.text_field :twitter_username %>
</div>
<div class="field">
<%= f.label :github_username %><br />
<%= f.text_field :github_username %>
</div>
<div class="field">
<%= f.label :website %><br />
<%= f.text_field :website %>
</div>
<% end %>
[/html]

user_steps/_form.html.erb

[html]
<%= form_for @user, url: wizard_path do |f| %>
<% if @user.errors.any? %>
<div class="error_messages">
<h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= yield f %>

<div class="actions">
<%= f.submit "Continue" %>
or <%= link_to "skip this step", next_wizard_path %>
</div>
<% end %>
[/html]

users/new.html.erb

[html]
<h1>Sign Up</h1>

<%= form_for @user do |f| %>
<% if @user.errors.any? %>
<div class="error_messages">
<h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>

<div class="actions">
<%= f.submit "Sign Up" %>
</div>
<% end %>
[/html]

users_controller.rb

[ruby]
def create
@user = User.new(params[:user])
if @user.save
session[:user_id] = @user.id
redirect_to user_steps_path
else
render :new
end
end
[/ruby]

models/user.rb

[ruby]
validates_format_of :twitter_username, without: /W/, allow_blank: true
# validates_presence_of :twitter_username, if: :on_social_step?
[/ruby]

Screencast: DataTables

DataTables erleichtert die Erstellung von Tabellen in HTML und unterstützt dabei seitenweise Navigation, Sortierung und Suchen. Ryan zeigt in diesem Screencast wie es in Rails eingesetzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

Gemfile

[ruby]
group :assets do
gem ‚jquery-datatables-rails‘, github: ‚rweng/jquery-datatables-rails‘
gem ‚jquery-ui-rails‘
end

gem ‚will_paginate‘
[/ruby]

app/assets/javascripts/application.js

[javascript]
//= require dataTables/jquery.dataTables
[/javascript]

app/assets/stylesheets/application.css

[css]
/*
*= require jquery.ui.core
*= require jquery.ui.theme
*= require dataTables/src/demo_table_jui
*/
[/css]

app/assets/javascripts/products.js.coffee

[javascript]
jQuery ->
$(‚#products‘).dataTable
sPaginationType: "full_numbers"
bJQueryUI: true
bProcessing: true
bServerSide: true
sAjaxSource: $(‚#products‘).data(’source‘)
[/javascript]

views/products/index.html.erb

[html]
<table id="products" class="display" data-source="<%= products_url(format: "json") %>">
<thead>
<tr>
<th>Product Name</th>
<th>Category</th>
<th>Release Date</th>
<th>Price</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
[/html]

products_controller.rb

[ruby]
def index
respond_to do |format|
format.html
format.json { render json: ProductsDatatable.new(view_context) }
end
end
[/ruby]

app/datatables/products_datatable.rb

[ruby]
class ProductsDatatable
delegate :params, :h, :link_to, :number_to_currency, to: :@view

def initialize(view)
@view = view
end

def as_json(options = {})
{
sEcho: params[:sEcho].to_i,
iTotalRecords: Product.count,
iTotalDisplayRecords: products.total_entries,
aaData: data
}
end

private

def data
products.map do |product|
[
link_to(product.name, product),
h(product.category),
h(product.released_on.strftime("%B %e, %Y")),
number_to_currency(product.price)
]
end
end

def products
@products ||= fetch_products
end

def fetch_products
products = Product.order("#{sort_column} #{sort_direction}")
products = products.page(page).per_page(per_page)
if params[:sSearch].present?
products = products.where("name like :search or category like :search", search: "%#{params[:sSearch]}%")
end
products
end

def page
params[:iDisplayStart].to_i/per_page + 1
end

def per_page
params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 10
end

def sort_column
columns = %w[name category released_on price]
columns[params[:iSortCol_0].to_i]
end

def sort_direction
params[:sSortDir_0] == "desc" ? "desc" : "asc"
end
end
[/ruby]

Screencast: Copycopter

Copycopter ist eine Plugin um Texte in Rails auf einfache Weise zu bearbeiten. Erst kürzlich wurde es von Thoughtbot als OpenSource freigegeben und steht nun somit allen Interessierten zur Verfügung. Ryan zeigt diese Woche wie es installiert und in eigenen Applikationen benutzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

terminal

[bash]
heroku login
git clone git://github.com/copycopter/copycopter-server.git
cd copycopter-server
heroku create –stack cedar
bundle install –without=test # if heroku command fails
git push heroku master
heroku run rake db:migrate
heroku restart
heroku run rake copycopter:project NAME=Store USERNAME=ryanb PASSWORD=secret
heroku open
[/bash]

Gemfile

[ruby]
gem ‚copycopter_client‘, ‚2.0.0‘
[/ruby]

config/initializers/copycopter.rb

[ruby]
CopycopterClient.configure do |config|
config.api_key = ‚8df4bc164dd6bc5574eb1efd0499ddcb‘
config.host = ’strong-dawn-1901.herokuapp.com‘
end
[/ruby]

app/views/products/index.html.erb

[html]
<h1><%= t "products.headline", default: "Browse Products" %></h1>
<em><%= t ".tagline", default: "We have what you need at a great low price." %></em>
[/html]

Screencast: Compass & CSS Sprites

Compass ist eine Ergänzung zu SASS indem es viele Benutzte Elemente noch weiter vereinfacht. Es werden z.B. vorgefertigte Mixin-Ins, Funktionen und mehr zur Verfügung gestellt. In diesem Screencast zeigt Ryan wie es verwendet wird und zusätzlich wie Compass für CSS-Sprites genutzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

Gemfile

[ruby]
group :assets do
gem ‚compass-rails‘
end
[/ruby]

app/assets/stylesheets/application.css.scss

[css]
@import "compass";
@import "compass/reset";
@import "layout";
[/css]

app/assets/stylesheets/layout.css.scss

[css]
h1 {
font-size: 28px;
font-weight: bold;
margin: 18px 0;
}

ul.horizontal {
@include horizontal-list;
}

@import "icons/*.png";
@include all-icons-sprites;

#nav_bar {
// …
@include background-image(linear-gradient(#5c5c5c, #111111));
}
[/css]

app/views/layouts/application.html.erb

[html]
<li><a class="icons-itunes" href="/itunes"></a></li>
<li><a class="icons-twitter" href="/twitter"></a></li>
<li><a class="icons-facebook" href="/facebook"></a></li>
<li><a class="icons-rss" href="/rss"></a></li>
[/html]

Screencast: Einführung in das Refinery CMS

Refinery ist ein CMS auf Basis von Rails und ermöglicht innerhalb kürzester Zeit ein lauffähiges System aufzusetzen. Wer schnell ein einfach bedienbares SMS aufsetzen möchte sollte sich dieses hier anschauen. Ryan führ in dieser Woche in Refinery ein und zeigt wie man damit einen Auftritt erstellt.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

terminal

[bash]
brew install imagemagick
gem install refinerycms
refinerycms piano_plus
cd piano_plus
rails s
[/bash]

config/initializers/refinery/core.rb

[ruby]
config.site_name = "Piano Plus"
[/ruby]

config/initializers/refinery/pages.rb

[ruby]
config.new_page_parts = true
[/ruby]

rails console

[ruby]
Refinery::Page.first.parts.create! title: "Banner"
[/ruby]

Screencast: Besseres Sass mit Bourbon

Bourbon ist ein Sass Mixin und stellt zahlreiche Funktionen für die Erstellung von Design-Elementen zur Verfügung. Dabei werden für die verschiedenen Browser auch die teilweise noch nötigen Prefixe verwendet. Ryan zeigt diese Woche wie es mit Rails zusammen verwendet werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

Gemfile

[ruby]
gem ‚bourbon‘
[/ruby]

app/assets/stylesheets/application.css.scss

[css]
@import "bourbon";
@import "layout";
@import "projects";
[/css]

app/assets/stylesheets/layout.css.scss

[css]
body {
margin: 0;
padding: 0;
background-color: #FFF;
font-size: 14px;
font-family: $verdana;
}

#header {
color: #FFF;
padding: 15px 100px;
font-size: 30px;
font-weight: bold;
@include linear-gradient(#777, #444);
@include box-shadow(0 0 6px 3px #000);
}

#container {
margin: 0 100px;
}

a {
color: #2D6DD2;
}
[/css]

app/assets/stylesheets/projects.css.scss

[css]
.project {
border: solid 1px #AAA;
margin: 20px 0;
padding: 7px 12px;
@include border-radius(6px);
@include transition(all, 500ms, ease-in-out);

&:hover { background-color: #F8FCCF; }

h2 {
margin: 0;
a { text-decoration: none; }
}
}

.new_project {
@include button(simple, #3FB344);
text-decoration: none;
font-size: 16px;
}
[/css]

Screencast: Einführung in Twitter Bootstrap

Twitter Bootstrap bietet ein Toolkit für die Erstellung von Webseiten, welches verschiedenste Elemente mitbringt und somit die Basisarbeiten vereinfachen soll. Es kann selbstverständlich auch in Rails-Applikationen eingesetzt werden und mit den entsprechenden Plugins wird auch hier dem Entwickler arbeit abgenommen. Ryan führ in diesem Screencast vor wie die Integration in Rails erfolgen und wie es verwendet werden kann.

 

Downloads in verschiedenen Formaten:

mp4
mp4
webm
ogg

 

Resourcen:

terminal

[bash]
rails new store
rails g scaffold product name price:decimal –skip-stylesheets
rake db:migrate
rails g bootstrap:install
rails g bootstrap:themed products -f
[/bash]

Gemfile

[ruby]
group :assets do
gem ‚twitter-bootstrap-rails‘
end
[/ruby]

layouts/application.html.erb

[html]
<!DOCTYPE html>
<html>
<head>
<title>Store</title>
<!–[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
<![endif]–>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="#">Some Store</a>
<div class="nav-collapse">
<ul class="nav">
<li><%= link_to "Browse Products", products_path %></li>
<li><%= link_to "Price List" %></li>
<li><%= link_to "Contact Us" %></li>
<li><%= link_to "Cart" %></li>
</ul>
</div>
</div>
</div>
</div>

<div class="container">
<div class="row">
<div class="span9"><%= yield %></div>
<div class="span3">
<h2>About Us</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
</div>
</body>
</html>
[/html]

app/assets/stylesheets/bootstrap_and_override.css.less

[css]
@import "twitter/bootstrap/bootstrap";

body { padding-top: 60px; }

@import "twitter/bootstrap/responsive";
[/css]

Screencast: Daten an JavaScript übergeben

Fast jeder hatte bereits die Anforderung Daten zwischen einer Rails-Applikation im Backend mit Java-Script im Frontend auszutauschen. Sei es auch nur um bestimmte Teile der Seite mit Java-Script zu markieren (z.B. Highlighting von Navigation oder Suchbegriffen). Es gibt verschiedenste Ansätze und alle bringen ihre eigenen Vor- und Nachteile mit. In diesem Screencast zeigt Ryan Drei verschiedene Ansätze wie es auch implementiert werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

products/index.html.erb

[html]
<%= javascript_tag do %>
window.productsURL = "<%=j products_url %>";
window.products = <%=raw Product.limit(10).to_json %>;
<% end %>
[/html]

app/assets/javascripts/products.js.coffee

[javascript]
jQuery ->
alert productsURL
[/javascript]

products/index.html.erb

[html]
<%= content_tag "div", id: "products", data: {products: Product.limit(10)} do %>
Loading products…
<% end %>
[/html]

app/assets/javascripts/products.js.coffee

[javascript]
jQuery ->
alert $(‚#products‘).data(‚products‘)
[/javascript]

Gemfile

[ruby]
gem ‚gon‘
[/ruby]

layouts/application.html.erb

[html]
<%= include_gon %>
[/html]

products_controller.rb

[ruby]
def index
gon.products = Product.limit(10)
# or
gon.rabl "app/views/products/index.json.rabl", as: "products"
end
[/ruby]

products/index.json.rabl

[javascript]
collection Product.limit(10)

attributes :id, :name, :price
[/javascript]

app/assets/javascripts/products.js.coffee

[javascript]
alert gon.products if gon
[/javascript]

Screencast: Im Browser „In-Place“ Editieren

In-Place Editing bezeichnet die Möglichkeit im Browser direkt Bereiche zu bearbeiten. Diese Funktion wird gerne CMS Systemen verwendet um den Anwender eine einfache Möglichkeit zu bieten um Inhalte ohne Umwege zu verändern und/oder zu erstellen. Ryan zeigt in diesem Screencast wie dies umgesetzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

Gemfile

[ruby]
gem ‚best_in_place‘
[/ruby]

app/assets/javascripts/application.js

[javascript]
//= require jquery.purr
//= require best_in_place
[/javascript]

app/assets/javascripts/users.js.coffee

[javascript]
jQuery ->
$(‚.best_in_place‘).best_in_place()
[/javascript]

users/show.html.erb

[html]
<p>
<b>Name:</b>
<%= best_in_place @user, :name %>
</p>
<p>
<b>Email:</b>
<%= best_in_place @user, :email %>
</p>
<p>
<b>Gender:</b>
<%= best_in_place @user, :gender, type: :select, collection: [["Male", "Male"], ["Female", "Female"], ["", "Unspecified"]] %>
</p>
<p>
<b>Public profile:</b>
<%= best_in_place @user, :public_profile, type: :checkbox, collection: %w[No Yes] %>
</p>
<p>
<%= best_in_place @user, :bio, type: :textarea %>
</p>
[/html]

users_controller.rb

[ruby]
respond_to :html, :json
def update
@user = User.find(params[:id])
@user.update_attributes(params[:user])
respond_with @user
end
[/ruby]

app/assets/stylesheets/users.css.scss

[css]
.purr {
position: fixed;
top: 30px;
right: 100px;
width: 250px;
padding: 20px;
background-color: #FCC;
border: solid 2px #C66;
&:first-letter { text-transform: uppercase; }
}
[/css]