Dela data med gester Rails & Heroku Setup

I del I i den här serien såg du hur vi gjorde en enkel mobilapp i Corona-ramen som svarar mot en "bump" -liknande åtgärd (kallad "thump") för att skicka ett meddelande till en annan mobilenhet. Kommunikationen mellan de två mobila enheterna sker mellan en mellanliggande serverprocess som matchar två "dumpade" enheter med både tidstämpel och avstånd. I denna handledning kommer vi att konfigurera den mellanliggande serverprocessen med Ruby on Rails.

Låt oss börja med att skapa vårt projekt. Eftersom vi använder geokit-plugin för att hjälpa till med våra geospatialberäkningar måste vi skapa detta projekt i Rails 2.3.5 eftersom plugin inte är 3,0 kompatibel.

Efter att du loggat in på ditt server / värdkonto (i vårt fall använder vi Heroku), skriv följande:

 mkdir thump-server cd thump-server / skenor. ta bort public / index.html

Ovanstående uttalanden kommer att skapa en katalog och starta ett nytt railsprojekt inuti det. Om du har 3.0 installerat på din utvecklingsmaskin kanske du behöver installera RVM och skapa en separat bildsats för detta projekt. Att göra detta ligger dock utanför handledningens omfattning. Nu ska vi installera geokit-plugin.

 script / plugin installera git: //github.com/andre/geokit-rails.git

När detta är klart måste vi lägga till vår pärla till projektet inuti Rails :: Initializer.run do | config | block av vår environment.rb-fil:

 config.gem "geokit"

Nu när det här pluginet har lagts till i projektet måste vi köra ett rake-kommando för att se till att alla nödvändiga pärlor är installerade i vårt system.

 rake gems: installera

Geokit bygger på databasen för att göra några ganska sofistikerade distansberäkningar. På grund av detta kommer den vanliga SQLite-databasen som ett railsprojekt kommer med inte att fungera. Geokit kräver att vi använder antingen en mysql eller postgres db för att lagra våra data. Trots att heroku använder postgres som standard är det vanligare att utvecklingsmaskiner har mysql installerat. Skönheten att använda Rails och ActiveRecord är att det spelar ingen roll. Vi kan utveckla vår app med MySQL och det kommer att fungera sömlöst med postgres.

 mysql -u root skapa databas thumpserver;

Nu uppdaterar vi vår database.yml-fil för att peka på vår nyutvecklade databas "thumpserver".

 utveckling: adapter: mysql databas: thumpserver användare: root socket: /tmp/mysql.sock pool: 5 timeout: 5000

Slutligen är vår projektskapande process klar. Vi kan börja koda logiken inuti vår thumpserver.

Rails har en enkel generator metod som skapar en REST baserad resurs för data CRUD. Om den sista meningen inte hade någon mening, föreslår jag dig att Google "rails restful resources" för att få veta mer. I huvudsak med ett kommando kan vi skapa en databas tabell, modell, controller och rutter inom projektet.

 ./ skript / generera resursdump enhetid: sträng lat: decimal lng: decimal meddelande: sträng mottagen: booleska

Vår resurs kallas thump, så genom att generera den på det här sättet kommer den att vara tillgänglig på webbläsaren när servern körs. Vi angav 5 fält som ska skapas för vår databas tabell:

deviceid: den mobila enhetens UID
lat: latitud som tillhandahålls av platstjänsten
Lng: longitud
meddelande: meddelandet som ska överföras till de användare som har dumpat
mottagen: detta är en booleska att markera en gång ett meddelande har mottagits så att det inte kan skickas igen

Rails kommer "automagiskt" skapa tidsstämpelfält som heter created_at och updated_at. Vi kommer att använda created_at senare i vårt exempel.

När vi genererade vår resurs skapades en migreringsfil för railsdatabas i mappen "db" i projektet. Filnamnet ska tyckas vara något så här: TIMESTAMP_create_thumps.rb

Vi måste ändra den här filen för att säkerställa att vår plats kan lagras med tillräckligt många decimaler. För att göra detta ersätter du bara dessa två linjer:

 t.decimal: lat t.decimal: lng

Med följande rader:

 t.decimal: lat,: precision => 8,: skala => 8 t.decimal: lng,: precision => 8,: skala => 8

Detta säkerställer att våra fält för breddgrad och longitud kan innehålla högst 8 decimaler.

För att undvika att "mottaget" fältet i vår databas är NULL måste vi lägga till en inställning så att dess värde är false som standard. Återigen kan vi göra det genom att ersätta den här raden:

 t.boolean: mottagen

Med den här raden:

 t.boolean: mottaget,: default => false

Nu när vår migrering är inställd kan vi köra rake-kommandot som faktiskt skapar tabellen i databasen:

 rake db: migrera

För att ta in ingångar för våra data använder vi "skapa" -åtgärden i vår thump controller. Utöver detta behöver vi en "sök" -åtgärd som tar några parametrar och söker igenom databasen för att matcha de två dumpade enheterna. Vi behöver ändra våra routes.rb i config-katalogen för att svara på URL / thump / search på en GET-förfrågan. Vi kan göra detta genom att ersätta den här raden:

 map.resources: thumps

Med denna linje

 map.resources: thumps,: collection => : search =>: get

Nästa upp, låt oss lägga till följande rader i vår thump.rb-fil inuti app / modeller.

 acts_as_mappable validates_presence_of: lat,: lng,: deviceid

Den första raden gör vår modell "mappable". Detta ger oss några extra sökmetoder som hjälper till att beräkna avståndet mellan två koordinatsatser. Nästa rad lägger till några enkla valideringar i vår thump-datamodell för att säkerställa att när vi får ett dumpmeddelande innehåller det rätt fält.

Slutligen får vi skapa våra åtgärder för att skapa och söka data i vår controller. Tack vare skönheten och enkelheten i ActiveRecord är vår "skapa" -aktion ganska enkel:

 def skapa Thump.create! (params [: thump]) render (: json => : success => true) räddning gör (: json => : success => false) slut

Om våra valideringar misslyckas returnerar vi ett json-objekt med: success => false. I del III av handledningen kommer vi att expandera vår mobilapp för att ta reda på detta.

Vår sökning "action" är lite mer komplex eftersom den använder några av frågesökarna från geokit:

 def: [: thump] [: lng]],: conditions => ["deviceid! =? OCH mottaget = ?: params [: thump] [: deviceid], false],: order => 'distans asc, created_at desc') höja om inte (thump) thump.update_attribute (: received, true) render success => true,: message => thump.message) räddning gör (: json => : success => false) slut

Låt oss bryta ner det här:

 thump = Thump.find (: first,: origin => [params [: thump] [: lat], parametrar [: thump] [: lng]],: conditions => ["deviceid! = , params [: thump] [: deviceid], false],: order => 'avstånd asc, created_at desc')

I huvudsak frågar vi efter vår "thump" match i databasen. En enhet kommer att skicka längs sin egen latitud och longitud som kommer att vara vår utgångspunkt. Våra förutsättningar säkerställer att vi inte av misstag hittar vår egen enhet genom att utesluta vår egen enhetstid från resultatuppsättningen. Vi vill också söka domar där "mottaget" fältet är felaktigt. För att hitta den närmaste matchen i både avstånd och tid, kommer vi att beställa våra resultat med avståndet mellan de 2 punkterna i stigande ordning (dvs närmast) och tid skapad eller skapad_ i nedåtgående ordning för att hitta den senaste. Det är uppenbarligen en osannolik händelse att det kommer att finnas några motstridiga "dunklar" för vår testapp, men den här typen av förfrågan kan hålla upp till en fleranvändarapplikation om vi ville ha det.

 höja om inte (thump) thump.update_attribute (: received, true) render (: json => : success => true,: message => thump.message)

Höjningskommandot stöder vår kodprogression i räddningsblocket som kommer att återvända: success => false om vi inte kan hitta en matchande trumma. Detta kommer att se till att vår mobilapp åtminstone tar emot något tillbaka om ett fel uppstår. Om objektet existerar kommer vi att sätta "mottaget" fältet till sant för att se till att det här meddelandet inte matchas i en efterföljande dataförfrågan. Vårt uttalande kommer att returnera ett JSON-objekt att enheten som mottar "thump" tolkar.

För att testa detta kan vi köra ett kommando i Rails-konsolen för att skapa en provrekord med en ursprungspunkt i New York City:

 Thump.create (: deviceid => "B",: lat => 40.7141667,: lng => - 74.0063889,: message => "B")

För att få en "thump" match eller en lyckad retur kan vi först starta vår server på standardport 3000:

 ./ Script / server

Och sedan slå följande webbadress:

http: // localhost: 3000 / dunkar / search dunka [Enhets] = A & dunka [lat] = 40,7141667 & dunka [LNG] = -74,0063889

Om allt går bra bör webbläsaren visa följande:

  "Meddelande": "B", "framgång": true

Detta simulerar en enhet som heter "A" som mottar ett "dunk" -meddelande från enhet B. Och där har vi det!

Nästa gång?

Stannade inställd på del III i serien, där vi kommer att driva serverns app till Heroku och uppgradera vår mobilapp för att kommunicera med servern.