Session in Ajax-Actions nutzen?

ja hallo erstmal,…

in der Webanwendung, an der ich derzeit arbeite, werden eine Attribute
eines
Objekts per Ajax geändert. Dazu habe ich das Objekt in die Session gelegt.
Bei normalen Aktion-Definitionen, wie new, create, etc. Methoden gelingt
dies
wunderbar. Ich greife dabei auf das Objekt mit session[:object] zu.

In Methoden, die für die Ajax-Aufrufe verwendet werden, (wie z.B.
def self.addStuff(param)… end) schlägt der Zugriff auf die Session fehl
(Fehlermeldung: TypeError (Symbol as array index)"

Wie kann ich in diesen Methoden auf meine Session zugreifen?

Danke,
Keep smiling
yanosz

def self.addStuff(param)… end ? Was genau ist das eigentlich für eine
Methode?

Da sie als Klassenmethode definiert wurde, kann ich nur mutmaßen, dass
sie sich in einem Deiner Models befindet?! Die session ist aber nur im
Controller- und View-Context verfügbar.

Liege ich einigermaßen richtig mit der Diagnose?

Gruß,
Martin


GL Networks
Martin R.
mail [email protected]
www http://www.glnetworks.de/

Ich freue mich immer über eine Empfehlung bei workingwithrails…
http://www.workingwithrails.com/recommendation/new/person/6641-martin-rehfeld

Hallo Yanosz/Jan(?),

vielleicht hab ich keine direkte Antwort auf deine Frage, sondern eher
einen Denkanstoß:

Ich kenne deine Anwendung zwar nicht und vielleicht hast du dafuer
einen guten Grund, aber normalerweise
ist es nicht ueblich, ganze Objekte in die Session zu legen. Du
solltest also zb nur die id des Objektes in die Session legen
bzw nur so wenig wie eben noetig. Es sprechen mehrere Dinge dagegen:

  1. Die Objekte muessen serialisiert werden, das heisst in die Session
    gemarschallt und wieder zurueck. Dafuer muss das erstmal
    gehen und wenn, dann laeufst du Gefahr, dass Benutzer mit ihrer
    Session im Nirvana landen und dir 500er Fehler um die Ohren fliegen,
    wenn du die Klasse veraenderst, bei ihnen aber noch die alte
    Serialisierung in der Session steckt.

  2. Wenn bei 1. alles gut gehen sollte, dann braucht das viel viel
    Speicherplatz und dein /tmp wird mit der Zeit richtig schoen gross.

  3. Wenn du auf Rails 2.0 umsteigst, dann wirst du mit den neuen
    Standardvorgehensweisen bei Sessions eventuell anecken.
    In 2.0 werden Sessions nicht mehr filebasiert auf dem Server abgelegt,
    sondern in Cookies, womit wird schon bei 4 waeren:

  4. Je nachdem was du in dem Objekt/Session stehen hast lagerst du
    sensible Daten auf den Client aus. Das wird zwar verschluesselt (in
    2.0),
    aber Vorsicht ist die Mutter der Porzelankiste.

  5. Aber am wichtigesten ist eigentlich, dass du mit dem Objekt in der
    Session die Trennung der Belange ein wenig durcheinander wirfst.
    Du hast deinen State im Controller und in der View also fast ueberall,
    aber eben nicht im Model. Es sollte zwischen Ajax und ‘normalen’
    Aktionen in deinem Controller zwar eine andere Behandlung geben (was
    liefere ich zurueck), aber die Aenderung des Application-States sollte
    (nur) im Model geschehen. Zu dem Thema gibt es eine Menge
    Blogeintraege, zb der:
    http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model

Was du mit self.addStuff meinst, kann ich im Moment nich ganz
nachvollziehen, aber es ist auch schon spaet. :slight_smile:
Warum arbeitest du da mit Klassenmethoden? session ist meines Wissens
nach eine Instanzmethode und auf die wirst du da so nicht zugreifen
koennen…
Vielleicht weiss das ja jemand genauer.

Viele Gruesse,
Tom

hier noch nen railscast, wieso man manche sachen nicht in ne session
packen sollte:

http://railscasts.com/episodes/13

mfg
manuel

ja hallo erstmal,…

Am Freitag, 12. Oktober 2007 schrieb Tom Winkler:

  1. Die Objekte muessen serialisiert werden, das heisst in die Session
    gemarschallt und wieder zurueck. Dafuer muss das erstmal
    gehen und wenn, dann laeufst du Gefahr, dass Benutzer mit ihrer
    Session im Nirvana landen und dir 500er Fehler um die Ohren fliegen,
    wenn du die Klasse veraenderst, bei ihnen aber noch die alte
    Serialisierung in der Session steckt.

Ok, das Problem ist nicht wirklich relavant, da es sich im eine interne
Anwendung mit max. 5 konkurrierenden Usern handelt.

  1. Wenn bei 1. alles gut gehen sollte, dann braucht das viel viel
    Speicherplatz und dein /tmp wird mit der Zeit richtig schoen gross.

Gibt’s denn kein Timeout?

  1. Wenn du auf Rails 2.0 umsteigst, dann wirst du mit den neuen
    Standardvorgehensweisen bei Sessions eventuell anecken.
    In 2.0 werden Sessions nicht mehr filebasiert auf dem Server abgelegt,
    sondern in Cookies, womit wird schon bei 4 waeren:

Moment - welchen Sinn macht das? Dann kann ich das Objekt doch auch
gleich in
den request rein-serialisieren, oder verstehe ich was falsch?

  1. Je nachdem was du in dem Objekt/Session stehen hast lagerst du
    sensible Daten auf den Client aus. Das wird zwar verschluesselt (in
    2.0),
    aber Vorsicht ist die Mutter der Porzelankiste.

So sensible sind die Daten nicht.

Was du mit self.addStuff meinst, kann ich im Moment nich ganz
nachvollziehen, aber es ist auch schon spaet. :slight_smile:
Warum arbeitest du da mit Klassenmethoden? session ist meines Wissens
nach eine Instanzmethode und auf die wirst du da so nicht zugreifen
koennen…
Vielleicht weiss das ja jemand genauer.

Also, ich muss vielleicht etwas weiter ausholen. Die Objekte, um die es
hier
geht, stehen in n:m Beziehungen mit anderen Objekten.
Wird ein Objekt bearbeitetet, so können referenzierte Objekte eingeschränkt,
embedded mitbearbeitet werden. Da diese Embedded-Masken an vielen Orten
auftauchen, haben wir sie in partials gepackt. Der Controller für die
partials - der ausschl. über Ajax angesprochen wird - erhält als Parameter
die aufrufende Instanz und triggert über reflection statische Methoden der
Kontrollerklasse des Aufrufers und übergibt ihr die Request-Parameter.
Bislang lief es so ab, dass in diesen statischen Methoden, das zu
bearbeitende Objekte über die übergebene ID aus der Datenbank geladen wurde.

Das führt jedoch zu dem Problem, dass nur bereits in der DB abgelegte Objekte
mit den Partial-Masken bearbeitet werden können - Wird ein Objekt neu
angelegt, so steht es für die Bearbeitung der Ajax-Requests nicht zu
verfügung.
Als Lösung wollte ich ein Objekt, das noch nicht “richtig” (also gerade in
der
Erzeugung seht) in der session ablegen, damit es auch bei der
Bearbeitung der
Ajax-Calls zur Verfügung steht.
Wenn man nicht aus einem statischen Kontext auf die Session zugreifen
kann
(was durchaus sinnvoll wäre g), so werde ich die session einfach als
Parameter übergeben.

Was die Kritik an der Ablage in der Session anbelangt: Mir fällt derzeit
nichts besseres ein.

  • Würde ich diese Objekte direkt in der DB ablegen, so würde die Datenbank
    zugemüllt, da hier nun überall (auch in den Referenztabellen) Objekte aus
    irgendwelche abgebrochenen Sitzungen liegen, die eigentlich gar nicht
    existieren. Würde anders als über die Webanwendung auf die DB zugegriffen,
    würde das für erhebliche irritationen sorgen -
    Oder ich führe wesentliche Tabellen doppelt, was wieder für erheblichen
    Aufwand in der Anpassung des DB-Modells sorgen würde. (Die DB-Struktur kommt
    aus einem ERM-Tool)
  • Die Daten in den Request zu legen, ist nicht gescheiht, da er Request
    vollständig in allen Ajax Calls übermittelt werden müsste.
  • Da es wie gesagt, nur darum geht, ein Objekt über mehrere Requests zu
    retten, bis es das erste Mal gespeichert wird, sollte der Punkt:
    Inkonsistenz
    zwischen DB und Session-Daten nicht greifen.

Wenn wir allerdings einen besseren Ort als die session wisst - nur raus
damit :wink:

Keep smiling
yanosz

Moinsens,

wo fange ich denn mal an :slight_smile:

Rails ist sehr eigen, was den richtigen Weg angeht. Prinzipiel geht
aber trotzdem alles, was man moechte, der große Unterschied
zwischen dem selbstgewaehlten und dem Rails-Weg ist allerdings, das
man sehr sehr viel mehr Arbeit investieren muss, wenn
man seinen Kopf durchsetzen moechte. Wenn irgendwas zu schwer ist,
dann ist man meistens auf dem falschen Weg.

Womit wir auch bei Thema waeren: Natuerlich kannst du Objekte in der
Session speichern und natuerlich kannst du ueber Tricks auch mit Ajax
auf
diese Objekte zugreifen. Aber du solltest es nicht. Dabei macht es
keinen Unterschied, ob die Anwendung fuer dich, fuer 5 Leute im
Intranet oder
fuer ein zweites Twitterpublikum gedacht ist.

Zu deinen anderen Fragen:

  1. Wenn bei 1. alles gut gehen sollte, dann braucht das viel viel
    Speicherplatz und dein /tmp wird mit der Zeit richtig schoen gross.

Gibt’s denn kein Timeout?

Meines Wissens nicht, wo soll das Timeout herkommen? Du kannst dir
einen Cronjob basteln, der die Files immer mal wieder loescht.

den request rein-serialisieren, oder verstehe ich was falsch?
Du solltst ja eben keine Objekte irgenwohin serialisieren. Sondern
eben nur die IDs und dann diese wieder damit aus der Datenbank holen.
Die Sessions als schnellen Zugriffsspeicher zu nutzen, ist nicht der
Sinn des ganzen. Wenn dir die Datenbank zu langsam ist - dann kannst
du eine geeignete Loesung wie memcached oder dergleichen einsetzen.

(nur) im Model geschehen. Zu dem Thema gibt es eine Menge
Also, ich muss vielleicht etwas weiter ausholen. Die Objekte, um die
Methoden der
Als Lösung wollte ich ein Objekt, das noch nicht “richtig” (also
derzeit
Aufwand in der Anpassung des DB-Modells sorgen würde. (Die DB-

Wenn wir allerdings einen besseren Ort als die session wisst - nur
raus
damit :wink:

Hier hats mich echt ein bisschen verlassen :wink: Vielleich denkst du zu
kompilziert, vielleicht ich zu einfach, aber
da steig ich nicht hinter. Vielleicht hilft dir das ja weiter.

http://railscasts.com/episodes/73
http://railscasts.com/episodes/74

Wenn du einen Presenter brauchst, dann schau dir mal
http://agilewebdevelopment.com/plugins/simplypresentable
oder aehnliche Loesungen an.

Beste Gruesse,
tom_______________________________________________
rubyonrails-ug mailing list
[email protected]
http://mailman.headflash.com/mailman/listinfo/rubyonrails-ug

Hallo Jan,

Jan L. schrieb:

Wie ist eigentlich der Rails-Weg, um im “Create”-Modus mit n:m Referenzen
umgehen zu können?

Das ist eine sehr gute Frage, die mich auch brennend interessiert. Ich
habe Ryan B. gebeten (mit einer kleinen Spende) diese Sachen bei
seiner Complex Form Screencast-series doch in Zukunft auch zu erwähnen.
Mal schauen was dabei rauskommt.

Bei mir ist das Szenario in etwa so:

  • User kann Message erstellen
  • Jede Message hat m Receiver die wiederum Contacts sinds.

Receivers ist quasi die Join Table (hasmany :through) zwischen Messages
und Contacts.

Wenn nun der User eine Message erstellt, kann er entweder einen
bestehenden Contact auswählen oder einen neuen erstellen. Logischerweise
können die Recipients erst erstellt werden, wenn die “parent” Message
eine primary id hat - und damit streng genommen die validation “hat
mindestens einen receiver” bricht.

Also ein Henne/Ei Problem das ich bisher mit einer transaction, save!
und danach einem manuellen valid? umgehe.
Allerdings habe ich auch in der view hacks, da m.W. die standard
formhelper nicht mit dem Einsatzzweck klarkommen.

Hat hier jemand bessere Ideen oder nen Link zu einem Tutorial?

Danke!

Mit freundlichen Gruessen,
Roland M.


Moriz Softwareentwicklung
Theresienstrasse 66
80333 Muenchen

Tel: 089 / 216 685 91
Fax: 089 / 216 685 92
Web: http://www.moriz.de/
Xing: https://www.xing.com/profile/Roland_MORIZ

Steuernummer: 145/217/70350
Finanzamt Muenchen III

ja hallo erstmal,…

Am Samstag, 13. Oktober 2007 schrieb Roland M.:

können die Recipients erst erstellt werden, wenn die “parent” Message
eine primary id hat - und damit streng genommen die validation “hat
mindestens einen receiver” bricht.

Also ein Henne/Ei Problem das ich bisher mit einer transaction, save!
und danach einem manuellen valid? umgehe.
Allerdings habe ich auch in der view hacks, da m.W. die standard
formhelper nicht mit dem Einsatzzweck klarkommen.

Hat hier jemand bessere Ideen oder nen Link zu einem Tutorial?

Ich muss zugeben, ich verstehe Dein Problem nicht ganz.

  • Du baust das Message Objekt und Hängst eine RecieverListe an - ok?
  • Validiert werden kann das ganze, da die Message Reciever hat.
  • Beim Abspeichern legst Du (macht ActiveRecord eigentlich automatisch)
    zuerst
    die Message in der DB an (keine fk-constraint knallt) und dann die
    recievers.

Praktisch gesehen hast du es also noch einfacher als ich: Es wird
praktisch
ausgeschlossen sein, dass zwei konkurierende User an der gleichen
Message
arbeiten, d.h. Du kannst alle Message-Daten im Formular speichern.

Ich hingeben verwende derzeit die Formulare des Edit-Falls wo sehr
leicht zwei
User an der gleichen Firma arbeiten könnten ebenfalls für den
create-Fall.
Daher entfällt bei mir die Möglichkeit alle Daten im Formular abzulegen.

Keep smiling
yanosz

ja hallo erstmal,…

Am Samstag, 13. Oktober 2007 schrieb Tom Winkler:

Moinsens,

wo fange ich denn mal an :slight_smile:

Rails ist sehr eigen, was den richtigen Weg angeht. Prinzipiel geht
aber trotzdem alles, was man moechte, der große Unterschied
zwischen dem selbstgewaehlten und dem Rails-Weg ist allerdings, das
man sehr sehr viel mehr Arbeit investieren muss, wenn
man seinen Kopf durchsetzen moechte. Wenn irgendwas zu schwer ist,
dann ist man meistens auf dem falschen Weg.

Sicher, das ist bei jedem Framework / jeder Sprache so.

Speicherplatz und dein /tmp wird mit der Zeit richtig schoen gross.

Gibt’s denn kein Timeout?

Meines Wissens nicht, wo soll das Timeout herkommen? Du kannst dir
einen Cronjob basteln, der die Files immer mal wieder loescht.

Cron? Wenn jmd. mit der Anwendung arbeitet, sollte es genug nutzbare
trigger
geben.

Du solltst ja eben keine Objekte irgenwohin serialisieren. Sondern
eben nur die IDs und dann diese wieder damit aus der Datenbank holen.
Die Sessions als schnellen Zugriffsspeicher zu nutzen, ist nicht der
Sinn des ganzen. Wenn dir die Datenbank zu langsam ist - dann kannst
du eine geeignete Loesung wie memcached oder dergleichen einsetzen.

Ok, um die Ausführung mal auf den Punkt zu bringen: Es geht mir nich darum,
Objekte außerhalb der Datenbank zu persisitieren, sondern Objekte, erst
nach
dem “Create”-Formular in der Datenbank persistiert werden sollen
create-Formular gedrückt wurde) für Ajax-Calls zur Verfügung zu stellen.

Konkret: Wir verwalten Firmen und Adressen. Beide stehen in einer
n:m Beziehung. Vom Workflow der Anwendung her gibt es eine Maske, mitder
Firmen bearbeitet werden können. (Create & Edit sieht gleich aus - gleiches
Form-Partial).
In diesem Formular können einer Firma per Ajax Adressen zugewiesen werden:
D.h. Es muss möglich sein, einer Firma Adressen zuzuweisen, bevor die Firma
in
der Datenbank existiert.

Im create-Fall wäre ein Weg:
Ich lege das Objekt in spe schon in der DB ab und speichere die ID. Das
würde bedeuten, dass die Firmen persistiert werden muss, bevor die erste
Adresse
angelegt werden kann. D.h. ich persistiere Firmen, bevor der User auf
create
gedrückt hat. Bei diesem Weg (ist das der rails Weg?) müsste die DB-Struktur
erheblich angepasst werden. (-> Sehr viel Aufwand bei größeren Anwendungen)

Der andere Weg ist:
Ich lege das Objekt in der Session ab - bis zu dem Zeitpunkt, wo es das
erste
Mal wirklich in der DB persistiert werden kann - ab dann arbeite ich mit
IDs.

http://railscasts.com/episodes/73
http://railscasts.com/episodes/74

Ist interessant und zeigt für 1:n Beziehungen sicherlich einen schönen Weg -
bedeutet aber, dass ich alle Adressen in Formular-Feldern persistieren
muss.
D.h. alle Adressen werden bei einem create oder update mit Formulardaten
überschrieben. Könnte es aber nicht passieren (da n:m), dass vers. Benutzer
sich gegenseitig Daten überschreiben? Ebenweil sehr viele Adressen, die auch
von anderen Firmenobjekten referenziert werden, neu geschrieben werden?
(Derzeit ist es bei uns so, dass immer nur per Ajax einzelne, bestimmte
Adressen bearbeitet werden)

(Mir pers. gefällt an der Lösung auch nicht, dass bei einer Firma mit vielen
Adressen immer alle Addressen in einer HTML-Seite abglegt werden. Das
bläht
ein wenig…)

Wie ist eigentlich der Rails-Weg, um im “Create”-Modus mit n:m
Referenzen
umgehen zu können?

Wenn du einen Presenter brauchst, dann schau dir mal
http://agilewebdevelopment.com/plugins/simplypresentable oder aehnliche
Loesungen an.

Ist nicht so ganz das was ich suche…
Trotzdem danke.

Alles Gute

Hi,

Jan L. schrieb:

Also ein Henne/Ei Problem das ich bisher mit einer transaction, save!
und danach einem manuellen valid? umgehe.
Allerdings habe ich auch in der view hacks, da m.W. die standard
formhelper nicht mit dem Einsatzzweck klarkommen.

Hat hier jemand bessere Ideen oder nen Link zu einem Tutorial?

Ich muss zugeben, ich verstehe Dein Problem nicht ganz.

  • Du baust das Message Objekt und Hängst eine RecieverListe an - ok?

Da die Receiver Contacts enthält, muss ich erst jeden Contact
finden/anlegen, bei Fehlern wieder alles zurückrollen. Das muss ich
alles “von Hand” tun. Im View (weil es dafür m.W keine Helper gibt) und
im Controller.

  • Validiert werden kann das ganze, da die Message Reciever hat.

Das funktioniert nur nachdem ich die Message gespeichert habe und
diese eine primary id hat. Damit sind die Validations eigentlich schon
verletzt (Message muss mindestens einen Receiver haben)

  • Beim Abspeichern legst Du (macht ActiveRecord eigentlich automatisch) zuerst
    die Message in der DB an (keine fk-constraint knallt) und dann die recievers.

Jein. Die Receiver schon, die Contacts dahiner nicht.

Ich speichere zuerst die Contacts, dann die Message mit Receivers und
jedesmal prüfen dass a) Contacts valid b) Message valid und c) Receiver
valid und ausserdem natürlich das mindestens ein Receiver da ist.

Nochmal zurück zur View:

Wenn der User den Mailtext “falsch” ausfüllt und aber auch keine
Contact-Mail angibt, soll beides sofort als invalid erkannt und
entsprechend angezeigt werden.

Für den Controller heisst es, dass ich einmal komplett durch validieren
muss und nicht beim ersten Fehler z.B. in einem Contact (vgl.
Reihenfolge mit oben) aussteigen kann.

Praktisch gesehen hast du es also noch einfacher als ich: Es wird praktisch
ausgeschlossen sein, dass zwei konkurierende User an der gleichen Message
arbeiten, d.h. Du kannst alle Message-Daten im Formular speichern.

jein, sobald die “Contacts” shared sind, habe ich auch hier ein Problem
(s.o. wenn eine Transaktion zurückrollt und die darüber neu erstellen
Contacts wieder gelöscht werden - und es keine doppelten Contacts geben
darf.)

Mit freundlichen Gruessen,
Roland M.


Moriz Softwareentwicklung
Theresienstrasse 66
80333 Muenchen

Tel: 089 / 216 685 91
Fax: 089 / 216 685 92
Web: http://www.moriz.de/
Xing: https://www.xing.com/profile/Roland_MORIZ

Steuernummer: 145/217/70350
Finanzamt Muenchen III

ja hallo erstmal,…
Am Sonntag, 14. Oktober 2007 schrieb Roland M.:

Ich muss zugeben, ich verstehe Dein Problem nicht ganz.

  • Du baust das Message Objekt und Hängst eine RecieverListe an - ok?

Da die Receiver Contacts enthält, muss ich erst jeden Contact
finden/anlegen, bei Fehlern wieder alles zurückrollen. Das muss ich
alles “von Hand” tun. Im View (weil es dafür m.W keine Helper gibt) und
im Controller.

Hmm… den Punkt verstehe ich nicht ganz. Du hast im controller
warhscheinlich
eine Action findOrCreate (oder wie auch immer). Diese Methode schaut ob
es
den Benutzer schon gibt, falls nein, validiert er ob er angelegt werden
könnte. Das ganze rendert ein rjs-Template, das entweder einen Fehler
schreibt oder den Kontakt mit id, oder den Anlegedaten in das Formular
schreibt. (Soweit nehme ich, dass das ganze kein Problem ist).

D.h. wenn du das Formular submittest, sind alle contacte schon in einem
Persitierfähigen zustand.

  • Validiert werden kann das ganze, da die Message Reciever hat.

Das funktioniert nur nachdem ich die Message gespeichert habe und
diese eine primary id hat. Damit sind die Validations eigentlich schon
verletzt (Message muss mindestens einen Receiver haben)

Entweder verstehe ich nicht, wo dein Problem ist, oder Du siehst die
Lösung
nicht.
Betrachten wir erstmal die Ruby-Welt:
Wir haben, da wir persistierfähige Kontakte haben, auf jeden Fall
Recieverobjekte.
SNIPP
contact.each{ | contact| recievers << new Reciever(:contact => contact)}
SNAPP
Gleichzeitig können wir der Message die reciever zuweisen.
SNIPP
message.recievers << recievers
SNAPP
Somit sind in der Ruby-Welt alle Bedigungen erfüllt. Schauen wir uns
jetzt die
SQL Welt an.
-> Message kann persisitiert werden (oder validation-error-Schmeißen)
-> Nun persisitiere alle Kontakte (hier können keine Fehler auftreten)
-> Als letztes Persistiere die Reciever - auch hier können keine Fehler
auftreten.

Schauen wir mal in die View.
-> wir haben Formular, dass die Message-Felder rendert und eine
Möglichkeit
zum suchen / anlegen von Kontakten bietet - ich würde einfach ein
Autocomplete Feld nehmen)
-> Wir haben ein rjs-Template, dass falls neue Kontakte einfügt werden,
diese
einfach in das Formular schreibt. (Neue Textfelder anhängt, etc.)

Das sollte ziemlich Basics sein.

Und im Controller: Bei geschickter Wahl der Feldnamen (also irgendwas
wie
contact[a[name]], lassen sich alle contact-Objekte in einer Hand voll
Zeilen
anlegen. Den Rest des Controllers habe ich oben ausgeführt.

jein, sobald die “Contacts” shared sind, habe ich auch hier ein Problem
(s.o. wenn eine Transaktion zurückrollt und die darüber neu erstellen
Contacts wieder gelöscht werden - und es keine doppelten Contacts geben
darf.)

Moment, du hast doch nur create/show für contacts - und falls sich mal
ein
Kontakt in Luft auflöst, sagt dir das sql sehr schnell.

Keep smiling
yanosz

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs