@drawoharajag ❤️ det här! << klicka på mig 🐛 🫖 🧚
/dangling-rpc-fruit-off-of-your-rails-controllers
publicerad den: 2013-11-05

När du arbetar med någon rails-applikation som inte är en hello-world-applikation behöver du ofta små ajax-hjälpmedel för att kommunicera med servern - för att kunna utföra klientlogik. Jag talar inte om ett api i sig, utan ad-hoc-verktyg som det här:

markdown.change(function(){
  generate_html_on_the_server( markdown.val(), function(html){
  
    preview.html(html);
  
  });
});

eller

reservation.change(function(){
  check_availibity_on_the_server( reservation.val(), function(data){
  
    if(!data['available']){
     
     alert('den tiden är inte tillgänglig - välj en annan!');
     
    };
  })
});

osv.

Dessa typer av funktioner ingår inte i ett server-till-server-api, de är bara samarbetande js/backend-slutpunkter som behövs för att vyn ska fungera.

De flesta rails-applikationer kommer att samla många av dessa och frågan uppstår:

“Var ska man lägga dem?”

I de flesta team kommer du att ha tre eller fyra utvecklare som namnger och organiserar dessa funktioner på olika sätt, vilket säkerställer att kodbasen blir ett cowboy-spaghetti-kaos inom kort.

På @dojo4 har vi abstraherat det här med en liten rpc-designmönster: först har vi en liten kontrollerdsl som ingår i vår ApplicationController som tillåter deklarativa definitioner av 'rpc' js-hjälpmedel på en per-kontrollerbasis.

class ApplicationController < ActionController::Base
  include(RPC)
end

Se implementationen här: https://gist.github.com/ahoward/7320900

På ren engelska definierar denna dsl bara en enda åtgärd på kontrollern som multiplexar vilken metod som ska användas baserat på parametrar, och ett enkelt sätt att definiera dem. Den förväntar sig att alla rpc-åtgärder returnerar en hash och ger tillbaka json.

Dess implementation går ut på

  def rpc
    which = params['method']
    
    action = @rpc[which]
    
    result = action.call(params)
    
    render :json => result.to_json
  end

Dess användning bör vara uppenbar från koden

class GeoLocationController < ApplicationController
  rpc(:geo_location) do |params|
    geo_location = GeoLocation.geo_locate( params['address']