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
- 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
- Logic in one place
- Can be part of a domain model in the server
- May be slow, because we have to wait to the server
- 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
- 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
- May be slow because we have to wait to the 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 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
- Logic in one place
- Can be part of a domain model in the client
- Fast, because we don`t wait to the server
- Not sure about business 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 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
- Fast, because we don`t wait to the server
- Logic in many places
- Maybe a nightmare is comming
Personally I'd go for #4 with a few small adjustments:
For the controller, consider doing a nested route. You would access the route by posting to
/notifications/1/acknowledgements
and then access the notification id withparams[:notification_id]
.Note: If there are multiple users in the system you may want to find the notification based on the
current_user
as opposed to accessing directly through theNotification
model. i.e.current_user.notifications.find(params[:notification_id])
I was having trouble coming up with a name for the controller. I landed on
acknowledgements
thinking that theNotification
has beenacknowledged
once it has been read. There may be a better name for it.If you ever decide to have an option to check as
unread
then you could just add a DELETE action to this controller andmark_as_unread
.You always want to have data validation on your server side.