SlideShare a Scribd company logo
1 of 39
Download to read offline
A Better UJS for Rails
Codemy.net
presents
@zacksiriby:
Monday, June 10, 13
Javascript is a big part of Rails Project
Monday, June 10, 13
No real convention for
working with JS files
Monday, June 10, 13
Backbone is Great but...
Monday, June 10, 13
I miss working with Ruby
Monday, June 10, 13
And then I saw Turbolinks...
Monday, June 10, 13
Monday, June 10, 13
Turbolinks Backbone / MV*
Control / Complexity for Client
Less Ruby
Monday, June 10, 13
So I thought long and hard
Monday, June 10, 13
Turbolinks Backbone / MV*
?
Something is
missing
Control / Complexity for Client
Less Ruby
Monday, June 10, 13
Transponder JS
http://www.github.com/zacksiri/transponder
Extracted from Codemy
Monday, June 10, 13
3 Core Components
• Helpers
• Presenters
• Services
Monday, June 10, 13
CH.calendar = Codemy.Helpers.Calendar =
  dateOnly: (date_time) ->
    moment(date_time).format('YYYY-MM-DD')
 
  timeInISO: (date_time) ->
    moment(date_time).format('YYYY-MM-DD HH:mm:ss Z')
 
  timeInHour: (date_time) ->
    moment(date_time).format('HH:mm A')
Monday, June 10, 13
class CommentsPresenter extends Transponder.Presenter
  presenterName: 'comments'
  modelName: 'comment'
 
  index: ->
    if @params.page
      CH.infiniteLoader.loadNext
        element: @element
        response: @response
        modelName: @modelName
        putAt: 'prepend'
 
  show: ->
    $(@element).replaceWith(@response)
    $(@element).trigger('codemy:services:highlight')
 
....
 
  create: ->
    $('#new_comment').replaceWith(@response)
    $(".comment:last").effect('highlight', {}, 500)
 
  destroy: ->
    $(@element).fadeOut 300, ->
      $(this).remove()
Monday, June 10, 13
• maps to your controller actions
• calls helper functions when needed
• trigger services
• modify the DOM as needed
Presenters
Monday, June 10, 13
How does it work?
Monday, June 10, 13
class CommentsPresenter extends Transponder.Presenter
  presenterName: 'comments'
  modelName: 'comment'
 
  index: ->
    # your code for modifying the DOM
    # listens for event ujs:comments:index
 
  update: ->
    # listens for even ujs:comments:update
...
• ujs:comments:index triggers index()
• ujs:comments:show triggers show()
• ujs:comments:edit triggers edit()
• ujs:comments:update triggers update()
• ujs:comments:create triggers create()
• ujs:comments:destroy triggers destroy()
Monday, June 10, 13
Ok so how do I trigger the
event?
Monday, June 10, 13
$('#comments').trigger("<%= j ujs_event_type %>", "<%= j
render 'comments' %>");
app/views/comments/index.js.erb
app/views/comments/update.js.erb
$('#comment_1').trigger("<%= j ujs_event_type %>", "<%= j
render @comment %>");
{
ujs:comments:update
{
controller_name:action_name
Monday, June 10, 13
class CommentsPresenter extends Transponder.Presenter
  presenterName: 'comments'
  modelName: 'comment'
 
  index: ->
    if @params.page
      CH.infiniteLoader.loadNext
        element: @element
        response: @response
        modelName: @modelName
        putAt: 'prepend'
 
  update: ->
    $(@element).replaceWith(@response)
 
  ...
Monday, June 10, 13
Presenters Provide
• Better code reusability (Dryer)
• Cleaner
• Provides Structure
• Use what you already know!
• Logicless View in Rails
Monday, June 10, 13
What are services?
Monday, June 10, 13
Monday, June 10, 13
<select>
  <option value="drafting">drafting</option>
  <option value="request_approval">
awaiting approval
</option>
</select>
Monday, June 10, 13
class Codemy.Services.SubmitOnChange extends
Transponder.Service
  serviceName: 'codemy:services:submit_on_change'
 
  serve: ->
    @element.on 'change', (e) ->
      e.preventDefault()
      form = $(this).parents('form')
      $.ajax
        url: form.attr('action')
        type: 'PUT'
        dataType: 'script'
        data: $(form).serialize()
Monday, June 10, 13
<select class="submit_on_change">
  <option value="drafting">drafting</option>
  <option value="request_approval">
awaiting approval
</option>
</select>
$('body.courses.index').trigger('codemy:services:submit_on_change');
<select class="submit_on_change submit_on_change_active">
  <option value="drafting">drafting</option>
  <option value="request_approval">
awaiting approval
</option>
</select>
Monday, June 10, 13
Transponder.service_manifest = ->
  $("body.questions,
     body.apprentice.objectives.show,
     body.mentor.owned_levels.show,
     body.mentor.objectives.show,
     body.mentor.posts,
     body.posts.show").trigger       'codemy:services:live_preview'
 
  $("body.questions,
     body.mentor.posts").trigger     'codemy:services:tag_select'
 
  $("body.questions,
     body.apprentice,
     body.mentor,
     body.activities,
     body.posts.show").trigger       'codemy:services:highlight'
Monday, June 10, 13
What Services Do
• Write once use everywhere (again Dryer code)
• Better Maintainability
• Makes sure it doesn’t run on a node that has that service
already running
• Makes it easier to manage all your code via manifest
Monday, June 10, 13
How do they all Work
Together?
Monday, June 10, 13
class BadgesPresenter extends Transponder.Presenter
  nameSpace: "mentor"
  presenterName: "badges"
  modelName: "badge"
 
  show: ->
    $(@element).replaceWith(@response)
    $(@element).trigger('codemy:services:poller')
    $(@element).trigger('codemy:services:uploader')
 
  update: ->
    @show()
Monday, June 10, 13
Monday, June 10, 13
$(document).ready
triggers uploader service
User
uploads uploader service runs
Runs Update action in
Presenter
Triggers poller
service
renders processed image to
browser
through presenter
1
2
3
4
5
6
Monday, June 10, 13
Transponder works with
Everything
Monday, June 10, 13
Not Saying don’t use
Backbone
Monday, June 10, 13
Use the right tools for
the job.
Monday, June 10, 13
Codemy uses Turbolinks with
Transponder and Backbone when
appropriate
Monday, June 10, 13
Transponder is out!
http://www.github.com/zacksiri/transponder
Monday, June 10, 13
# TODO:
• Clean up some APIs
• Add Documentation
• Video Screencasts
• More Generators
• Example Rails Project
Monday, June 10, 13
Thank You!
@codemy_net
Questions?
@zacksiri
Monday, June 10, 13

More Related Content

Similar to A Better UJS for Rails

Bytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMBytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMashleypuls
 
Deprecating ActiveRecord Attributes without making Zombies
Deprecating ActiveRecord Attributes without making ZombiesDeprecating ActiveRecord Attributes without making Zombies
Deprecating ActiveRecord Attributes without making Zombiesyann ARMAND
 
Nomethoderror talk
Nomethoderror talkNomethoderror talk
Nomethoderror talkJan Berdajs
 
Angular JS Routing
Angular JS RoutingAngular JS Routing
Angular JS Routingkennystoltz
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin Cataldo
 
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014John Hann
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UIRebecca Murphey
 
Lone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AngleLone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AnglePablo Godel
 
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...Rob Tweed
 
Gon gem. For RDRC 2013, June 7
Gon gem. For RDRC 2013, June 7Gon gem. For RDRC 2013, June 7
Gon gem. For RDRC 2013, June 7Alexey Gaziev
 
JavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & BrowserifyJavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & BrowserifyJohan Nilsson
 
PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010
PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010
PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010Lincoln III
 
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложения
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложенияCodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложения
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложенияCodeFest
 
Puppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolPuppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolMiki Lombardi
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionPaul Irish
 
jQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformancejQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformanceAndrás Kovács
 
Introduction à AngularJS
Introduction à AngularJSIntroduction à AngularJS
Introduction à AngularJSNicolas PENNEC
 
Using Angular with Rails
Using Angular with RailsUsing Angular with Rails
Using Angular with RailsJamie Davidson
 

Similar to A Better UJS for Rails (20)

Bytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMBytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASM
 
Deprecating ActiveRecord Attributes without making Zombies
Deprecating ActiveRecord Attributes without making ZombiesDeprecating ActiveRecord Attributes without making Zombies
Deprecating ActiveRecord Attributes without making Zombies
 
Nomethoderror talk
Nomethoderror talkNomethoderror talk
Nomethoderror talk
 
Angular JS Routing
Angular JS RoutingAngular JS Routing
Angular JS Routing
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
Zero-config JavaScript apps with RaveJS -- SVCC fall 2014
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UI
 
Lone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AngleLone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New Angle
 
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
 
Gon gem. For RDRC 2013, June 7
Gon gem. For RDRC 2013, June 7Gon gem. For RDRC 2013, June 7
Gon gem. For RDRC 2013, June 7
 
JavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & BrowserifyJavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & Browserify
 
PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010
PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010
PrettyFaces URLRewrite for Servlet & JavaEE @ Devoxx 2010
 
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложения
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложенияCodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложения
CodeFest 2014. Пухальский И. — Отзывчивые кроссплатформенные веб-приложения
 
Puppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolPuppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing Tool
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
AngularJS and SPA
AngularJS and SPAAngularJS and SPA
AngularJS and SPA
 
jQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformancejQuery Anti-Patterns for Performance
jQuery Anti-Patterns for Performance
 
Introduction à AngularJS
Introduction à AngularJSIntroduction à AngularJS
Introduction à AngularJS
 
Backbone
BackboneBackbone
Backbone
 
Using Angular with Rails
Using Angular with RailsUsing Angular with Rails
Using Angular with Rails
 

Recently uploaded

Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sectoritnewsafrica
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessWSO2
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...amber724300
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Recently uploaded (20)

Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with Platformless
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

A Better UJS for Rails

  • 1. A Better UJS for Rails Codemy.net presents @zacksiriby: Monday, June 10, 13
  • 2. Javascript is a big part of Rails Project Monday, June 10, 13
  • 3. No real convention for working with JS files Monday, June 10, 13
  • 4. Backbone is Great but... Monday, June 10, 13
  • 5. I miss working with Ruby Monday, June 10, 13
  • 6. And then I saw Turbolinks... Monday, June 10, 13
  • 8. Turbolinks Backbone / MV* Control / Complexity for Client Less Ruby Monday, June 10, 13
  • 9. So I thought long and hard Monday, June 10, 13
  • 10. Turbolinks Backbone / MV* ? Something is missing Control / Complexity for Client Less Ruby Monday, June 10, 13
  • 12. 3 Core Components • Helpers • Presenters • Services Monday, June 10, 13
  • 13. CH.calendar = Codemy.Helpers.Calendar =   dateOnly: (date_time) ->     moment(date_time).format('YYYY-MM-DD')     timeInISO: (date_time) ->     moment(date_time).format('YYYY-MM-DD HH:mm:ss Z')     timeInHour: (date_time) ->     moment(date_time).format('HH:mm A') Monday, June 10, 13
  • 14. class CommentsPresenter extends Transponder.Presenter   presenterName: 'comments'   modelName: 'comment'     index: ->     if @params.page       CH.infiniteLoader.loadNext         element: @element         response: @response         modelName: @modelName         putAt: 'prepend'     show: ->     $(@element).replaceWith(@response)     $(@element).trigger('codemy:services:highlight')   ....     create: ->     $('#new_comment').replaceWith(@response)     $(".comment:last").effect('highlight', {}, 500)     destroy: ->     $(@element).fadeOut 300, ->       $(this).remove() Monday, June 10, 13
  • 15. • maps to your controller actions • calls helper functions when needed • trigger services • modify the DOM as needed Presenters Monday, June 10, 13
  • 16. How does it work? Monday, June 10, 13
  • 17. class CommentsPresenter extends Transponder.Presenter   presenterName: 'comments'   modelName: 'comment'     index: ->     # your code for modifying the DOM     # listens for event ujs:comments:index     update: ->     # listens for even ujs:comments:update ... • ujs:comments:index triggers index() • ujs:comments:show triggers show() • ujs:comments:edit triggers edit() • ujs:comments:update triggers update() • ujs:comments:create triggers create() • ujs:comments:destroy triggers destroy() Monday, June 10, 13
  • 18. Ok so how do I trigger the event? Monday, June 10, 13
  • 19. $('#comments').trigger("<%= j ujs_event_type %>", "<%= j render 'comments' %>"); app/views/comments/index.js.erb app/views/comments/update.js.erb $('#comment_1').trigger("<%= j ujs_event_type %>", "<%= j render @comment %>"); { ujs:comments:update { controller_name:action_name Monday, June 10, 13
  • 20. class CommentsPresenter extends Transponder.Presenter   presenterName: 'comments'   modelName: 'comment'     index: ->     if @params.page       CH.infiniteLoader.loadNext         element: @element         response: @response         modelName: @modelName         putAt: 'prepend'     update: ->     $(@element).replaceWith(@response)     ... Monday, June 10, 13
  • 21. Presenters Provide • Better code reusability (Dryer) • Cleaner • Provides Structure • Use what you already know! • Logicless View in Rails Monday, June 10, 13
  • 24. <select>   <option value="drafting">drafting</option>   <option value="request_approval"> awaiting approval </option> </select> Monday, June 10, 13
  • 25. class Codemy.Services.SubmitOnChange extends Transponder.Service   serviceName: 'codemy:services:submit_on_change'     serve: ->     @element.on 'change', (e) ->       e.preventDefault()       form = $(this).parents('form')       $.ajax         url: form.attr('action')         type: 'PUT'         dataType: 'script'         data: $(form).serialize() Monday, June 10, 13
  • 26. <select class="submit_on_change">   <option value="drafting">drafting</option>   <option value="request_approval"> awaiting approval </option> </select> $('body.courses.index').trigger('codemy:services:submit_on_change'); <select class="submit_on_change submit_on_change_active">   <option value="drafting">drafting</option>   <option value="request_approval"> awaiting approval </option> </select> Monday, June 10, 13
  • 27. Transponder.service_manifest = ->   $("body.questions,      body.apprentice.objectives.show,      body.mentor.owned_levels.show,      body.mentor.objectives.show,      body.mentor.posts,      body.posts.show").trigger       'codemy:services:live_preview'     $("body.questions,      body.mentor.posts").trigger     'codemy:services:tag_select'     $("body.questions,      body.apprentice,      body.mentor,      body.activities,      body.posts.show").trigger       'codemy:services:highlight' Monday, June 10, 13
  • 28. What Services Do • Write once use everywhere (again Dryer code) • Better Maintainability • Makes sure it doesn’t run on a node that has that service already running • Makes it easier to manage all your code via manifest Monday, June 10, 13
  • 29. How do they all Work Together? Monday, June 10, 13
  • 30. class BadgesPresenter extends Transponder.Presenter   nameSpace: "mentor"   presenterName: "badges"   modelName: "badge"     show: ->     $(@element).replaceWith(@response)     $(@element).trigger('codemy:services:poller')     $(@element).trigger('codemy:services:uploader')     update: ->     @show() Monday, June 10, 13
  • 32. $(document).ready triggers uploader service User uploads uploader service runs Runs Update action in Presenter Triggers poller service renders processed image to browser through presenter 1 2 3 4 5 6 Monday, June 10, 13
  • 34. Not Saying don’t use Backbone Monday, June 10, 13
  • 35. Use the right tools for the job. Monday, June 10, 13
  • 36. Codemy uses Turbolinks with Transponder and Backbone when appropriate Monday, June 10, 13
  • 38. # TODO: • Clean up some APIs • Add Documentation • Video Screencasts • More Generators • Example Rails Project Monday, June 10, 13