Skip to content

Instantly share code, notes, and snippets.

@adriancuadros
Forked from bhserna/where_is_the_app.markdown
Last active December 10, 2015 15:39
Show Gist options
  • Select an option

  • Save adriancuadros/4456118 to your computer and use it in GitHub Desktop.

Select an option

Save adriancuadros/4456118 to your computer and use it in GitHub Desktop.

Where is the app?

This are different examples of doing the same thing, "mark a notification as read", and the pros and cons that I see in each example

1. - Logic in the model

  • The user clicks the notification link
  • The system POSTs to the action "notifications/:id/mark_as_read"
  • The controller calls the method Notification#mark_as_read
  • The model updates the attribute "read" saves the Notification record
  • And sends the response back to the client
class App.NotificationView

  constructor: (@el, @notification) ->
    @el.click => @notification.markAsRead()
      
class App.Notification extends App.Model

  markAsRead: ->
    unless @get('read')
      $.ajax
        url: "notifications/#{@get 'id'}/mark_as_read"
        type: 'POST'
        dataType: "json"
        success: (json) =>
          @set('read', json.read)
class NotificationsController < ApplicationController
  def mark_as_read
    @notification = Notification.find(params[:id])
    @notification.mark_as_read
    return json: @notification
  end
end

class Notification < ActiveRecord::Base
  def mark_as_read
    update_attributes read: true
  end
end

Pros

  • Logic in one place
  • Can be part of a domain model in the server

Cons

  • May be slow, because we have to wait to the server

2.- Logic in the controller

  • The user clicks the notification link
  • The client POSTs to the action "notifications/:id/mark_as_read"
  • The controller updates the attribute "read" of the notification record and then saves it
  • And sends the response back to the client
class App.NotificationView

  constructor: (@el, @notification) ->
    @el.click => @notification.markAsRead()
      
class App.Notification extends App.Model

  markAsRead: ->
    unless @get('read')
      $.ajax
        url: "notifications/#{@get 'id'}/mark_as_read"
        type: 'POST'
        dataType: "json"
        success: (json) =>
          @set('read', json.read)
class NotificationsController < ApplicationController
  def mark_as_read
    @notification = Notification.find(params[:id])
    @notification.update_attributes read: true
    return json: @notification
  end
end

Pros

  • Logic that is only used in that case does not go in the model
  • Looks like the controller serves only to call a method from the client

Cons

  • May be slow because we have to wait to the server

3.- Logic in the client

  • The user clicks the notification link
  • The Notification#mark_as_read, method of a client model, that modifies the "read" attribute (backbone.js or something like that)
  • The client updates to "notifications/:id" in the server
class App.NotificationView

  constructor: (@el, @notification) ->
    @el.click =>
      @notification.markAsRead()
      @notification.save()
      
class App.Notification extends App.Model

  markAsRead: ->
    @set('read', true)
class NotificaitiosController < ApplicationController
  def update
    @notification = Notification.find(params[:id])
    @notification.update_attributes(params[:notificaiton])
  end
end

Pros

  • Logic in one place
  • Can be part of a domain model in the client
  • Fast, because we don`t wait to the server

Cons

  • Not sure about business logic, in the client

4.- Logic client and server

  • The user clicks the notification link
  • The Notification#mark_as_read, method of a client model, that modifies the "read" attribute (backbone.js or something like that)
  • The client POSTs to the action "notifications/:id/mark_as_read"
  • The controller calls the method Notification#mark_as_read
  • The model updates the attribute "read" and saves the Notification record
  • And sends the response back to the client
class App.NotificationView

  constructor: (@el, @notification) ->
    @el.click => @notification.markAsRead()
      
class App.Notification extends App.Model

  markAsRead: ->
    @set('read', true)
    $.ajax
      url: "notifications/#{@get 'id'}/mark_as_read"
      type: 'POST'
      dataType: "json"
      success: (json) =>
        @set('read', json.read)
class NotificationsController < ApplicationController
  def mark_as_read
    @notification = Notification.find(params[:id])
    @notification.mark_as_read
    return json: @notification
  end
end

class Notification < ActiveRecord::Base
  def mark_as_read
    update_attributes read: true
  end
end

Pros

  • Fast, because we don`t wait to the server

Cons

  • Logic in many places
  • Maybe a nightmare is comming
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment