Download - A Better UJS for Rails
![Page 1: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/1.jpg)
A Better UJS for Rails
Codemy.net
presents
@zacksiriby:
Monday, June 10, 13
![Page 2: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/2.jpg)
Javascript is a big part of Rails Project
Monday, June 10, 13
![Page 3: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/3.jpg)
No real convention for working with JS files
Monday, June 10, 13
![Page 4: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/4.jpg)
Backbone is Great but...
Monday, June 10, 13
![Page 5: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/5.jpg)
I miss working with Ruby
Monday, June 10, 13
![Page 6: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/6.jpg)
And then I saw Turbolinks...
Monday, June 10, 13
![Page 7: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/7.jpg)
Monday, June 10, 13
![Page 8: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/8.jpg)
Turbolinks Backbone / MV*
Control / Complexity for Client
Less Ruby
Monday, June 10, 13
![Page 9: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/9.jpg)
So I thought long and hard
Monday, June 10, 13
![Page 10: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/10.jpg)
Turbolinks Backbone / MV*
?Something is
missing
Control / Complexity for Client
Less Ruby
Monday, June 10, 13
![Page 11: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/11.jpg)
Transponder JS
http://www.github.com/zacksiri/transponder
Extracted from Codemy
Monday, June 10, 13
![Page 12: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/12.jpg)
3 Core Components
• Helpers
• Presenters
• Services
Monday, June 10, 13
![Page 13: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/13.jpg)
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
![Page 14: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/14.jpg)
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
![Page 15: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/15.jpg)
• maps to your controller actions
• calls helper functions when needed
• trigger services
• modify the DOM as needed
Presenters
Monday, June 10, 13
![Page 16: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/16.jpg)
How does it work?
Monday, June 10, 13
![Page 17: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/17.jpg)
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
![Page 18: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/18.jpg)
Ok so how do I trigger the event?
Monday, June 10, 13
![Page 19: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/19.jpg)
$('#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
![Page 20: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/20.jpg)
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
![Page 21: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/21.jpg)
Presenters Provide
• Better code reusability (Dryer)
• Cleaner
• Provides Structure
• Use what you already know!
• Logicless View in Rails
Monday, June 10, 13
![Page 22: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/22.jpg)
What are services?
Monday, June 10, 13
![Page 23: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/23.jpg)
Monday, June 10, 13
![Page 24: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/24.jpg)
<select> <option value="drafting">drafting</option> <option value="request_approval"> awaiting approval </option></select>
Monday, June 10, 13
![Page 25: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/25.jpg)
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
![Page 26: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/26.jpg)
<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
![Page 27: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/27.jpg)
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
![Page 28: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/28.jpg)
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
![Page 29: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/29.jpg)
How do they all Work Together?
Monday, June 10, 13
![Page 30: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/30.jpg)
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
![Page 31: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/31.jpg)
Monday, June 10, 13
![Page 32: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/32.jpg)
$(document).readytriggers uploader service
User uploads uploader service runs
Runs Update action in Presenter
Triggers poller service
renders processed image to browser
through presenter
1
23
45
6
Monday, June 10, 13
![Page 33: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/33.jpg)
Transponder works with Everything
Monday, June 10, 13
![Page 34: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/34.jpg)
Not Saying don’t use Backbone
Monday, June 10, 13
![Page 35: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/35.jpg)
Use the right tools for the job.
Monday, June 10, 13
![Page 36: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/36.jpg)
Codemy uses Turbolinks with Transponder and Backbone when
appropriate
Monday, June 10, 13
![Page 37: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/37.jpg)
Transponder is out!
http://www.github.com/zacksiri/transponder
Monday, June 10, 13
![Page 38: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/38.jpg)
# TODO:
• Clean up some APIs
• Add Documentation
• Video Screencasts
• More Generators
• Example Rails Project
Monday, June 10, 13
![Page 39: A Better UJS for Rails](https://reader034.vdocuments.us/reader034/viewer/2022052619/556315fed8b42a5b498b4ea4/html5/thumbnails/39.jpg)
Thank You!
@codemy_net
Questions?
@zacksiri
Monday, June 10, 13