<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ruby &#8211; webmatze.de</title>
	<atom:link href="https://webmatze.de/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>https://webmatze.de</link>
	<description>Profi Tipps für einen erfolgreichen Internetauftritt</description>
	<lastBuildDate>Fri, 19 Dec 2025 19:15:37 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>
	<item>
		<title>Recordables in Rails: Delegated Types praxisnah erklärt</title>
		<link>https://webmatze.de/recordables-in-rails-delegated-types-praxisnah-erklaert/</link>
					<comments>https://webmatze.de/recordables-in-rails-delegated-types-praxisnah-erklaert/#respond</comments>
		
		<dc:creator><![CDATA[Mathias Karstädt]]></dc:creator>
		<pubDate>Fri, 19 Dec 2025 19:15:37 +0000</pubDate>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Recordable Pattern]]></category>
		<category><![CDATA[ruby]]></category>
		<guid isPermaLink="false">https://webmatze.de/?p=1122</guid>

					<description><![CDATA[In diesem Beitrag zeige ich dir das Recordable Pattern, das 37signals (Basecamp, HEY) einsetzt, und erkläre es Schritt für Schritt anhand von lauffähigen Rails-Code-Beispielen. Zielgruppe sind Anfänger bis Fortgeschrittene Ruby on Rails Entwickler, die polymorphe Datenmodelle sauber, skalierbar und gut paginierbar bauen möchten. Warum das Ganze? Klassische Ansätze wie Single Table Inheritance (STI) oder „nackte“ [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>In diesem Beitrag zeige ich dir das Recordable Pattern, das 37signals (Basecamp, HEY) einsetzt, und erkläre es Schritt für Schritt anhand von lauffähigen Rails-Code-Beispielen. Zielgruppe sind Anfänger bis Fortgeschrittene Ruby on Rails Entwickler, die polymorphe Datenmodelle sauber, skalierbar und gut paginierbar bauen möchten.</p>
<p><iframe title="The Rails Delegated Type Pattern with Jeffrey Hardy" width="500" height="281" src="https://www.youtube.com/embed/m90sl-Uvu0Y?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<p>Warum das Ganze? Klassische Ansätze wie Single Table Inheritance (STI) oder „nackte“ polymorphe Assoziationen stoßen schnell an Grenzen: STI bläht Tabellen auf, polymorphes CRUD bleibt oft mühsam zu paginieren. Das Recordable Pattern nutzt Rails’ <a href="http://https://api.rubyonrails.org/classes/ActiveRecord/DelegatedType.html" title="Delegated Types">Delegated Types</a>, um eine dünne, performante „Superklasse“-Tabelle (Recording) mit schlanken „Subklasse“-Tabellen (Recordables wie Message, Document, Comment) zu kombinieren.</p>
<hr />
<h2>Das Grundprinzip</h2>
<ul>
<li>Eine zentrale Tabelle <strong>„recordings“</strong> hält alle gemeinsamen Metadaten (z. B. Bucket, Creator, Timestamps) und verweist polymorph auf den „konkreten Inhalt“ (recordable).</li>
<li>Jede konkrete Recordable (Message, Document, Comment) hat eine eigene Tabelle mit genau ihren Feldern.</li>
<li>Abfragen, Pagination und gemeinsame Logik passieren über Recording; konkretes Verhalten (z. B. <code>export_html</code>) lebt bei den Recordables.</li>
</ul>
<p>So bleibst du:</p>
<ul>
<li>flexibel (neue Typen ohne Recording-Migration),</li>
<li>performant (einheitliche Timeline auf der dünnen Recording-Tabelle),</li>
<li>sauber getrennt (Metadaten vs. Inhalte).</li>
</ul>
<hr />
<h2>Minimales Datenmodell</h2>
<p>Migration (gekürzt auf das Wesentliche):</p>
<pre><code class="language-ruby">create_table :recordings do |t|
  t.references :bucket,  null: false, foreign_key: true
  t.references :creator, null: false, foreign_key: { to_table: :users }
  t.string  :recordable_type, null: false
  t.bigint  :recordable_id,   null: false
  t.index [:recordable_type, :recordable_id]
  t.bigint :parent_id # optional: Recording-Baum (Unterelemente)
  t.index :parent_id
  t.timestamps
end
add_foreign_key :recordings, :recordings, column: :parent_id

create_table :messages do |t|
  t.string :title,   null: false
  t.text   :content, null: false
  t.timestamps
end

create_table :documents do |t|
  t.string :title, null: false
  t.text   :body
  t.string :external_url
  t.timestamps
end

create_table :comments do |t|
  t.text :body, null: false
  t.timestamps
end</code></pre>
<hr />
<h2>Models und Concerns</h2>
<p>Recording: die „Superklasse“ mit Delegation</p>
<pre><code class="language-ruby">class Recording &lt; ApplicationRecord
  belongs_to :bucket
  belongs_to :creator, class_name: &quot;User&quot;

  delegated_type :recordable, types: %w[Message Document Comment], dependent: :destroy

  # optional: Baumstruktur
  belongs_to :parent, class_name: &quot;Recording&quot;, optional: true
  has_many   :children, class_name: &quot;Recording&quot;, foreign_key: :parent_id, dependent: :nullify

  # Bequeme Filter-Scopes kommen mit delegated_type:
  # Recording.messages, Recording.documents, Recording.comments
end</code></pre>
<p>Recordable-Concern: gemeinsame API für Inhalte</p>
<pre><code class="language-ruby">module Recordable
  extend ActiveSupport::Concern

  included do
    has_many :recordings, as: :recordable, inverse_of: :recordable
  end

  def display_title
    respond_to?(:title) ? title : self.class.name
  end

  def export_html
    &quot;#{display_title}&quot;
  end
end</code></pre>
<p>Konkrete Typen:</p>
<pre><code class="language-ruby">class Message &lt; ApplicationRecord
  include Recordable
  validates :title, :content, presence: true

  def export_html
    &quot;#{title}#{content}&quot;
  end
end

class Document &lt; ApplicationRecord
  include Recordable
  validates :title, presence: true

  def export_html
    if external_url.present?
      &quot;#{title}External: #{external_url}&quot;
    else
      &quot;#{title}#{body}&quot;
    end
  end
end

class Comment &lt; ApplicationRecord
  include Recordable
  validates :body, presence: true

  def display_title
    body.truncate(40)
  end

  def export_html
    &quot;#{body}&quot;
  end
end</code></pre>
<hr />
<h2>Erstellen und Paginieren einer Timeline</h2>
<p>Bucket kapselt die Aufnahme neuer Inhalte („record“) und die Timeline. Bucket ist hier eher abstrakt und könnte genausogut auch ein Projekt sein, oder ein Kunde:</p>
<pre><code class="language-ruby">class Bucket &lt; ApplicationRecord
  has_many :recordings, dependent: :destroy

  def timeline(limit: 50)
    recordings.order(created_at: :desc).limit(limit).includes(:recordable)
  end

  def record(recordable, creator:, parent: nil, color: nil)
    recordings.create!(recordable: recordable, creator: creator, parent: parent, color: color)
  end
end</code></pre>
<p>Typische Abfragen:</p>
<pre><code class="language-ruby">bucket = Bucket.find(1)

# Gesamte Timeline effizient paginieren
bucket.timeline(limit: 50).each do |rec|
  puts &quot;[#{rec.recordable_type}] #{rec.recordable.display_title}&quot;
end

# Nur bestimmte Typen (Scopes via delegated_type)
Recording.messages.where(bucket: bucket).limit(20)
Recording.documents.where(bucket: bucket).order(created_at: :desc)</code></pre>
<hr />
<h2>Versionierung per Repointing (immutable Recordables)</h2>
<p>Statt Inhalte zu „updaten“, erzeugst du neue Recordables und verweist die Recording-Zeile auf die neue Version. Das hält Historie sauber und macht Kopieren effizient.</p>
<pre><code class="language-ruby">class Recording &lt; ApplicationRecord
  # ...

  def repoint_to!(new_recordable)
    update!(recordable: new_recordable)
  end
end

# Beispiel: Message ? neue Document-Version
msg_rec = bucket.record(Message.create!(title: &quot;Kickoff&quot;, content: &quot;Welcome!&quot;), creator: user)
new_doc = Document.create!(title: &quot;Specs v2&quot;, body: &quot;Updated requirements&quot;)
msg_rec.repoint_to!(new_doc) # Recording zeigt nun auf Document</code></pre>
<p>Wenn du eine echte Ereignis-Historie brauchst, ergänze ein <code>Event</code>-Model und schreibe beim <code>record</code>/<code>repoint_to!</code> Einträge (z. B. „created“, „repointed“, inkl. vorher/nachher <code>recordable_type/_id</code>). Das hält Audit-Trails und erlaubt Timeline-Features (siehe Video/37signals-Artikel).</p>
<hr />
<h2>Copy &amp; Move: Subtrees kopieren</h2>
<p>Ein Vorteil des Patterns: Kopieren und Verschieben ganzer Teilbäume wird planbar und schnell, weil Recordings leichtgewichtig sind und Recordables immutable dupliziert werden. Eine einfache Kopier-Serviceklasse:</p>
<pre><code class="language-ruby">class Copier
  def self.copy!(source_recording:, destination_bucket:, creator:)
    new(source_recording, destination_bucket, creator).copy!
  end

  def initialize(source_recording, destination_bucket, creator)
    @source_recording   = source_recording
    @destination_bucket = destination_bucket
    @creator            = creator
  end

  def copy!
    ActiveRecord::Base.transaction do
      copied_root = copy_recording(@source_recording, parent: nil)
      @source_recording.children.each { |child| copy_branch(child, parent: copied_root) }
      copied_root
    end
  end

  private

  def copy_branch(node, parent:)
    copied = copy_recording(node, parent: parent)
    node.children.each { |child| copy_branch(child, parent: copied) }
    copied
  end

  def copy_recording(original, parent:)
    new_recordable = duplicate_recordable(original.recordable)
    @destination_bucket.record(new_recordable, creator: @creator, parent: parent, color: original.color)
  end

  def duplicate_recordable(recordable)
    case recordable
    when Message
      Message.create!(title: recordable.title, content: recordable.content)
    when Document
      Document.create!(title: recordable.title, body: recordable.body, external_url: recordable.external_url)
    when Comment
      Comment.create!(body: recordable.body)
    else
      raise ArgumentError, &quot;Unsupported recordable: #{recordable.class.name}&quot;
    end
  end
end</code></pre>
<hr />
<h2>Vergleich mit STI und „plain“ Polymorphismus</h2>
<ul>
<li><strong>STI</strong>: Einfache Fälle ok. Bei divergenten Typen entsteht Tabellen-Bloat, viele NULL-Spalten, Migrationen werden groß, Erweiterbarkeit leidet.</li>
<li><strong>Polymorphismus ohne <code>delegated_type</code></strong>: Funktioniert, aber es fehlen bequeme Scopes/Convenience-Methoden; unified Pagination ist oft hakelig.</li>
<li><strong>Recordables + <code>delegated_type</code></strong>: Einheitliche Timeline über eine dünne Tabelle, klare Trennung von Meta vs. Inhalt, leichte Erweiterbarkeit (neuen Typ hinzufügen statt zentrale Tabelle migrieren), gute Performance bei Abfragen.</li>
</ul>
<hr />
<h2>Wann solltest du das Pattern nutzen?</h2>
<ul>
<li>Du brauchst eine gemischte, paginierbare Timeline (z. B. Aktivitätsfeed über Messages, Documents, Comments).</li>
<li>Deine Typen unterscheiden sich stark in ihren Attributen.</li>
<li>Du willst Polymorphismus am Parent (Recording) und saubere Delegation an die Inhalte.</li>
</ul>
<p>Wann eher nicht?</p>
<ul>
<li>Deine Subtypen sind fast identisch (STI könnte reichen).</li>
<li>Du hast keine gemeinsamen Abfragen über Typgrenzen hinweg.</li>
</ul>
<hr />
<h2>Best Practices</h2>
<ul>
<li>Halte Recording schlank: nur Metadaten und die polymorphe Referenz. Keine großen Textfelder.</li>
<li>Packe typenübergreifende Logik in Recording (oder Concerns), typenspezifische Logik in die Recordables.</li>
<li>Nutze <code>delegate</code> am Recording für gemeinsame Schnittstellen, z. B. <code>delegate :export_html, to: :recordable</code>.</li>
<li>Wenn Auditing/History wichtig ist, ergänze Events und schreibe Änderungen mit.</li>
<li>Autorisierung: Recording bündelt viele Aktionen – prüfe Berechtigungen konsequent.</li>
</ul>
<hr />
<h2>Fazit</h2>
<p>Das Recordable Pattern mit <code>delegated_type</code> ist eine elegante, praxiserprobte Lösung für polymorphe Inhalte in Rails. Es bringt dir:</p>
<ul>
<li>eine einheitliche, performante Timeline,</li>
<li>klare Verantwortlichkeiten zwischen Metadaten und Inhaltsobjekten,</li>
<li>einfache Erweiterbarkeit ohne große Migrationen,</li>
<li>saubere APIs durch Delegation.</li>
</ul>
<p>Wenn du Feed-ähnliche Strukturen, Versionierung und Kopier-Features brauchst, wirst du mit Recordings/Recordables sehr schnell produktiv.</p>
<p>Viel Spaß beim Ausprobieren – und schreib mir gern, wenn du Fragen hast oder Beispiele aus deinem Projekt teilen willst!</p>
<p>— Mathias (webmatze.de)</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webmatze.de/recordables-in-rails-delegated-types-praxisnah-erklaert/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DragonRuby Sokoban &#8211; Mein erstes Game auf itch.io</title>
		<link>https://webmatze.de/dragonruby-sokoban-mein-erstes-game-auf-itch-io/</link>
					<comments>https://webmatze.de/dragonruby-sokoban-mein-erstes-game-auf-itch-io/#respond</comments>
		
		<dc:creator><![CDATA[Mathias Karstädt]]></dc:creator>
		<pubDate>Thu, 12 Jan 2023 20:24:38 +0000</pubDate>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[DragonRuby]]></category>
		<category><![CDATA[ruby]]></category>
		<guid isPermaLink="false">https://webmatze.de/?p=966</guid>

					<description><![CDATA[Wenn man etwas Neues lernen möchte, ist es häufig am einfachsten, mit einem richtigen Projekt zu starten und dann bei dessen Umsetzung zu lernen. So habe ich es schon immer gemacht. Als ich Ruby lernen wollte, habe ich mir als Idee eine Event Veranstaltungsseite genommen und angefangen diese mit Ruby on Rails umzusetzen. Entstanden ist [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Wenn man etwas Neues lernen möchte, ist es häufig am einfachsten, mit einem richtigen Projekt zu starten und dann bei dessen Umsetzung zu lernen. So habe ich es schon immer gemacht. Als ich Ruby lernen wollte, habe ich mir als Idee eine Event Veranstaltungsseite genommen und angefangen diese mit <a href="https://rubyonrails.org/" title="Ruby on Rails">Ruby on Rails</a> umzusetzen. Entstanden ist Eventicus (leider offline) aber noch <a href="http://https://github.com/webmatze/eventicus.de" title="zu finden auf github.com">zu finden auf github.com</a>.</p>
<p>Als Jugentlicher wollte ich unbedingt <a href="http://https://winworldpc.com/product/turbo-pascal/7x" title="Turbo Pascal">Turbo Pascal</a> lernen und habe mir als Projekt ein einfaches Sokoban Spiel genommen und es umgesetzt. Im Laufe der Umsetzung habe ich vieles über Turbo Pascal gelernt und auch dessen Grenzen entdeckt. So musste ich z.B. einige der Grafikroutinen dann doch mit <a href="http://https://de.wikibooks.org/wiki/Assembler-Programmierung_f%C3%BCr_x86-Prozessoren/_Einleitung" title="Assembler">Assembler</a> umsetzen.</p>
<p>Da mich das Programmieren von grafischen Spielereien (Demos) oder eben auch gleich richtigen Spielen schon immer faziniert hat, habe ich mich auch gleich für das <a href="http://https://dragonruby.org/toolkit/game" title="DragonRuby Game Toolkit">DragonRuby Game Toolkit</a> interessiert. Dieses erlaubt es euch, mit Hilfe der Ruby Programmiersprache 2D oder auch 3D Spiele zu programmieren.</p>
<p>Und da ich wieder nach einer Idee für ein Spiel suchte, dachte ich mir: &quot;Hey, warum versucht du nicht einfach das gleiche Spiel wie damals umzusetzen?&quot;.</p>
<p>Gesagt – getan.</p>
<p>Also habe ich angefangen und entstanden ist dabei <a href="http://https://webmatze.itch.io/dragonruby-sokoban" title="DragonRuby Sokoban">DragonRuby Sokoban</a>. </p>
<p><iframe src="https://itch.io/embed/1873848?border_width=2" width="554" height="169" frameborder="0"><a href="https://webmatze.itch.io/dragonruby-sokoban">Dragonruby Sokoban by webmatze</a></iframe><br />
<span id="more-966"></span></p>
<p>Den Code findet ihr wie immer <a href="http://https://github.com/webmatze/dragonruby-sokoban-game" title="auf meinen GitHub Account">auf meinen GitHub Account</a>.</p>
<p>Und wer es nicht erwarten kann, kann das Spiel auch gleich hier ausprobieren:</p>
<p><iframe src="https://itch.io/embed-upload/7147494?color=333333" allowfullscreen="" width="1280" height="740" frameborder="0"><a href="https://webmatze.itch.io/dragonruby-sokoban">Play Dragonruby Sokoban on itch.io</a></iframe></p>
<p>Viel Spaß!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webmatze.de/dragonruby-sokoban-mein-erstes-game-auf-itch-io/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ReFiddle &#8211; Reguläre Ausdrücke direkt im Browser testen</title>
		<link>https://webmatze.de/refiddle-regulare-ausdrucke-direkt-im-browser-testen/</link>
					<comments>https://webmatze.de/refiddle-regulare-ausdrucke-direkt-im-browser-testen/#respond</comments>
		
		<dc:creator><![CDATA[Mathias Karstädt]]></dc:creator>
		<pubDate>Thu, 21 Jun 2012 16:45:27 +0000</pubDate>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[regular expressions]]></category>
		<category><![CDATA[ruby]]></category>
		<guid isPermaLink="false">http://webmatze.de/?p=736</guid>

					<description><![CDATA[Reguläre Ausdrücke direkt im Browser testen, mit diesem großartigem Tool.]]></description>
										<content:encoded><![CDATA[<p><strong>Egal in welcher Programmier- oder Scriptingsprache man programmiert, man wird früher oder später immer auf Reguläre Ausdrücke treffen.</strong></p>
<p>Wenn man erst mal verstanden hat, wie diese funktionieren, weiß man was für ein mächtiges Werkzeug man damit in der Hand hat. Allerdings sind komplizierte Reguläre Ausdrücke nicht gerade einfach zu schreiben und zu testen.</p>
<p>Nun gibt es ein neues browserbasiertes Tool, mit dem sich <a href="http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck">Reguläre Ausdrücke</a> sehr einfach und bequem schreiben und testen lassen.</p>
<figure id="attachment_740" aria-describedby="caption-attachment-740" style="width: 709px" class="wp-caption alignnone"><a href="http://webmatze.de/wp-content/uploads/2012/06/Bildschirmfoto-2012-06-21-um-18.35.42.png"><img loading="lazy" decoding="async" class=" wp-image-740 " title="ReFiddle" src="http://webmatze.de/wp-content/uploads/2012/06/Bildschirmfoto-2012-06-21-um-18.35.42.png" alt="" width="709" height="440" srcset="https://webmatze.de/wp-content/uploads/2012/06/Bildschirmfoto-2012-06-21-um-18.35.42.png 1013w, https://webmatze.de/wp-content/uploads/2012/06/Bildschirmfoto-2012-06-21-um-18.35.42-300x186.png 300w" sizes="auto, (max-width: 709px) 100vw, 709px" /></a><figcaption id="caption-attachment-740" class="wp-caption-text">ReFiddle - Reguläre Ausdrücke im Browser testen</figcaption></figure>
<p><a href="http://refiddle.com/">ReFiddle</a> (http://refiddle.com/) ist ganz ähnlich dem JavaScript Tool <a href="http://jsfiddle.net/">JsFiddle</a> aufgebaut. Oben befindet sich ein Eingabefeld für den Regulären Ausdruck, darunter kann man einen beliebigen Text eingeben, auf den dieser Ausdruck angewendet werden soll.</p>
<p>Auf der Linken Seite lassen sich verschiedene Optionen einstellen um z.B. alle möglichen Treffer zu finden (Match all occurrences) oder um die Groß- und Kleinschreibung zu ignorieren (Ignore case). Außerdem lässt sich auswählen, für welche Sprache man den Regulären Ausdruck schreiben möchte. Momentan gibt es hier nur JavaScript, Ruby und .Net zur Auswahl.</p>
<p>Ich finde, dass ReFiddle das Zeug zu einem häufig genutzten Tool hat. Großartig ist, dass sich eigene erstellte Reguläre Ausdrücke mit anderen teilen lassen. Ich bin mir auch sicher, dass bald Unterstützung für weitere Sprachen folgen wird.</p>
<p>Was haltet ihr von diesem Tool? Werdet ihr es nutzen?</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webmatze.de/refiddle-regulare-ausdrucke-direkt-im-browser-testen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ruby on Rails auf Ubuntu 11.10 installieren</title>
		<link>https://webmatze.de/ruby-on-rails-auf-ubuntu-11-10-installieren/</link>
					<comments>https://webmatze.de/ruby-on-rails-auf-ubuntu-11-10-installieren/#comments</comments>
		
		<dc:creator><![CDATA[Mathias Karstädt]]></dc:creator>
		<pubDate>Sat, 15 Oct 2011 14:17:06 +0000</pubDate>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ubuntu]]></category>
		<guid isPermaLink="false">http://webmatze.de/?p=689</guid>

					<description><![CDATA[Seit einigen Tagen (Oktober 2011) ist die neuste Version von Ubuntu zum Download freigegeben. Ubuntu 11.10 oder auch Oneiric Ocelot genannt, ist ein wirklich ausgereiftes und leicht zu bedienendes Linux Betriebssystem, welches kostenlos zum Download bereit steht. Da Linux schon von Natur aus viele Funktionen und Helfer für Programmierer bereit hält, eignet es sich auch [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Seit einigen Tagen (Oktober 2011) ist die neuste Version von <a title="Ubuntu Linux" href="http://www.ubuntu.com/">Ubuntu</a> zum <a title="Download Ubuntu hier" href="http://www.ubuntu.com/download">Download</a> freigegeben. <strong>Ubuntu 11.10</strong> oder auch <strong>Oneiric Ocelot</strong> genannt, ist ein wirklich ausgereiftes und leicht zu bedienendes Linux Betriebssystem, welches kostenlos zum Download bereit steht. Da Linux schon von Natur aus viele Funktionen und Helfer für Programmierer bereit hält, eignet es sich auch hervorragend zur Entwicklung von <strong>Ruby on Rails</strong> Anwendungen.</p>
<p><a title="Ruby on Rails" href="http://rubyonrails.org/">Ruby on Rails</a> hingegen ist derzeit eines der populärsten und produktivsten OpenSource Frameworks, mit dem sich sehr schnell umfangreiche Webanwendungen erstellen lassen. Wer schon damit gearbeitet hat, weiß wieviel Spaß es machen kann.</p>
<p><a title="Ruby Homepage" href="http://www.ruby-lang.org">Ruby</a> selbst ist eine Scriptsprache, wie z.B. auch PHP eine Scriptsprache ist. Ruby wurde jedoch von Grund auf mit dem Ziel entwickelt, leicht verständlich zu sein und eine schnelle Entwicklung damit zu ermöglichen.</p>
<h3>Ubuntu für Rails vorbereiten</h3>
<p>Damit wir das Rails Framework unter <strong>Ubuntu 11.10</strong> verwenden können, müssen wir zuerst <strong>Ruby</strong> installieren. Von Haus aus ist Ubuntu noch nicht mit Ruby ausgestattet, jedoch läßt sich dieses (und auch andere Programmiersprachen) sehr leicht nachträglich installieren.</p>
<p>Hierzu muss man wissen, dass es verschiedene Versionen von Ruby gibt. Ältere Versionen von Ruby on Rails haben hauptsächlich auf die <strong>Ruby Version 1.8.7</strong> gesetzt. Die neusten <strong>Ruby on Rails Versionen ab 3.0</strong> verwenden jedoch bevorzugt <strong>Ruby Version 1.9.2</strong>. Um unser System also für die Zukunft vorzubereiten, werden wir auf den <a title="Ruby Version Manager Homepage" href="http://beginrescueend.com/">Ruby Versions Manager</a> (RVM) setzen, mit dem es möglich ist jede beliebige Ruby Version zu installieren und auch bequem zwischen diesen zu wechseln.</p>
<p><span id="more-689"></span>Damit wir <strong>RVM</strong> installieren können, müssen wir zuerst ein paar Abhängigkeiten installieren:</p>
<pre>sudo apt-get install git
sudo apt-get install curl</pre>
<p>Git benötigen wir, weil die meisten <strong>Ruby on Rails</strong> Projekte und Erweiterungen ihre Sourcen mit <a title="Git SCM Homepage" href="http://git-scm.com/">Git</a> verwalten. Und curl brauchen wir, um mit dem folgenden Befehl <strong>RVM</strong> zu installieren:</p>
<pre>bash &lt; &lt;(curl -s https://rvm.beginrescueend.com/install/rvm)</pre>
<p>Nachdem dies ausgeführt wurde, bekommen wir noch ein paar Hinweise vom <strong>RVM</strong> Entwickler, wie wir damit umgehen können. Unter anderem wird auch noch darauf hingewiesen, dass folgende Abhängigkeiten installiert werden sollten, bevor man damit beginnen kann, ein oder mehrere Ruby Versionen zu installieren:</p>
<pre>sudo apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion</pre>
<p>Nun sollte man das Terminal einmal schließen und wieder ein neues Terminal öffnen und mit folgenden Befehl überprüfen, ob <strong>RVM</strong> richtig installiert wurde:</p>
<pre>type rvm | head -1</pre>
<p>Wird hier jetzt '<strong>rvm is a function</strong>' zurückgegeben, ist alles in Ordnung und wir können damit beginnen, unsere benötigte Ruby Version zu installieren.</p>
<h3>Ruby 1.9.2 auf Ubuntu installieren</h3>
<p>Abhängig davon, welche Ruby on Rails Version wir nutzen wollen, können wir nun die entsprechende Ruby Version installieren. Dies ist mit dem <strong>RVM</strong> Befehlt mehr als einfach. Gehen wir davon aus, dass wir <strong>Ruby on Rails 3.1</strong> (also die aktuelle Version) installieren wollen, können wir so <strong>Ruby 1.9.2</strong> installieren:</p>
<pre>rvm install 1.9.2</pre>
<p>Nach ein paar Minuten ist dann Ruby installieret. Beachten sollte man hierbei jedoch unbedingt, dass alles was man mit <strong>RVM</strong> macht ohne den <strong>sudo</strong> Befehlt ausgefürt werden muss! Warum dies so ist und weitere wichtige Nutzungshinweise erhaltet ihr in der <a title="RVM Dokumentation" href="http://beginrescueend.com/rvm/basics/"><strong>RVM</strong> Dokumentation</a>.</p>
<p>Um nun die installierte Ruby Version nutzen zu können, muss man sie mit dem folgenden Befehl aktivieren:</p>
<pre>rvm use 1.9.2</pre>
<p>Jetzt kann man überprüfen, welche Ruby Version installiert ist:</p>
<pre>ruby -v</pre>
<h3>Ruby on Rails auf Ubuntu installieren</h3>
<p>Nachdem nun alle notwendigen Vorbereitungen abgeschlossen sind, können wir damit beginnen die aktuelle Rails Version zu installieren. Rails und andere benötigte Packete werden mit dem <a title="RubyGems Package Manager" href="http://en.wikipedia.org/wiki/RubyGems">RubyGems Package Manager</a> installiert. Dieser wurde zum Glück auch schon automatisch von <strong>RVM</strong> mit installiert. Wir brauchen also nur noch folgendes auszuführen:</p>
<pre>gem install rails</pre>
<p>und schon wurde <strong>Ruby on Rails</strong> erfolgreich installiert. Auch hier ist wieder zu beachten, dass alle <strong>RubyGems</strong> ohne den <strong>sudo</strong> Befehl installiert werden.</p>
<h3>JavaScript Runtime installieren</h3>
<p>In der aktuellen <strong>Rails Version 3.1.1</strong> gibt es noch eine weitere Abhängigkeit, welche man beachten muss. Rails benötigt hier nämlich eine im System installierte <strong>JavaScript Runtime</strong> um bestimmte Funktionen ausführen zu können. Am einfachsten und problemlosesten konnte ich dieses Problem bei mir beheben, indem ich <a title="Node.js Homepage" href="http://nodejs.org/">Node.js</a> installiert habe:</p>
<pre>sudo apt-get install nodejs</pre>
<h3>Ruby on Rails testen</h3>
<p>Jetzt wo alles installiert ist, können wir schnell noch ein Testprojekt mit Rails erstellen:</p>
<pre>rails new test_app
cd test_app
rails server</pre>
<p>und uns dies im Browser aufrufen:</p>
<pre>http://localhost:3000</pre>
<p>Fertig ist unsere <strong>Ruby on Rails installation auf Ubuntu</strong>.</p>
<p>Die hier genannten Installationsschritte mögen sich mit denen auf anderen Ubuntu Versionen oder anderen Linux System unterscheiden.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://webmatze.de/ruby-on-rails-auf-ubuntu-11-10-installieren/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
