Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails - The Dark Side-2016

Rails - The Dark Side-2016

Rails is awesome! This is what everyone says. On this talk we will try to check all point of views about the framework. Rails can have some dark sides, horribles, actually. I will let you know what are those aspects/sides and how to avoid them. Many of the truths that we cling to depend on our point of view. Do not turn to the dark side!

Franzé Jr.

January 20, 2016
Tweet

More Decks by Franzé Jr.

Other Decks in Programming

Transcript

  1. JS.ERB create.js.erb $("#new_donation").modal("hide"); $("#new_donation").remove(); <%if @donation.state == "paid"%> var content

    = "<%=escape_javascript(render '/donations/approved_donation')%>"; <%else%> var content = "<%=escape_javascript(render '/donations/refused_donation')%>"; <%end%> ! $(".money #campaign").prepend(content).hide().slideDown() ! $(".money .box.donations").block() ! var donations_html = "<%=escape_javascript(render '/donations/donation', donation: @donation)%>"; $(".money .box.donations .no_donations").remove()/ $(".money .box.donations .transactions-list").append(donations_html); $(".money .box.donations").unblock()
  2. JS.ERB create.js.erb $("#new_donation").modal("hide"); $("#new_donation").remove(); <%if @donation.state == "paid"%> var content

    = "<%=escape_javascript(render '/donations/approved_donation')%>"; <%else%> var content = "<%=escape_javascript(render '/donations/refused_donation')%>"; <%end%> ! $(".money #campaign").prepend(content).hide().slideDown() ! $(".money .box.donations").block() ! var donations_html = "<%=escape_javascript(render '/donations/donation', donation: @donation)%>"; $(".money .box.donations .no_donations").remove()/ $(".money .box.donations .transactions-list").append(donations_html); $(".money .box.donations").unblock()
  3. JS.ERB • Client side ? Server side? • It doesn’t

    look good - mix of JS + ( HTML ) + Ruby ! var poll_stats_html = "<%=escape_javascript(render '/money_polls/money_use_option_stats') %>"; <% if params[:partial_id].present? %> var apend_to = "#feed_<%= params[:partial_id] %>_money_poll_<%=@money_poll.id%>"; <% else %> var apend_to = "#money_poll_<%=@money_poll.id%>"; <% end %> $(poll_stats_html).hide().appendTo(apend_to).fadeIn("slow");
  4. JS.ERB Complexity Logic in your javascript views to update the

    page var div = document.createElement("div"); var activities = $(div).html("<%=j render(@feed)%>"); TweenLite.to($(div).find(".activity"), 0, {opacity:0}); $('.ban2').append(activities); TweenMax.staggerTo($(div).find(".activity"), 0.6, {opacity:1}, 0.1); ! <% if @feed.next_page %> $('.pagination').replaceWith('<%= j will_paginate(@feed) %>'); <% else %> $('.pagination').remove(); $('.loadmore').remove(); <% end %>
  5. Compatibility / Versions Rails has serious problems with update gems

    and the Ruby version itself ! “The problem with Rails is not the pace of change so much as the wild changes of direction it takes, sometimes introducing serious performance degradations into official releases. Sometimes it's hard to see a guiding core philosophy other than the fact they want to be on the shiny edge”
  6. Learning Curve ❏ ERB Syntax! ❏ HAML/ SLIM! ❏ Puma/Thin!

    ❏ Capistrano! ❏ RSPEC/Minitest! ❏ Cucumber ❏ Ruby! ❏ Ruby Philosophy! ❏ Active Record! ❏ Gem Management / Bundler! ❏ Routing in Rails
  7. Scaffolding // Not a good idea ! ! “Rails is

    awesome because you can do a simple app in one day and it can help you in the creation”
  8. Scaffolding // Not a good idea • Inexperienced developers can

    put scaffold code in production • Don’t have notion about its features • Every project is different and you cannot think it will do all the same. • DO NOT use it professionally.
  9. Helpers Mix HTML/Ruby code module DeviseHelper def devise_error_messages! return ""

    if resource.errors.empty? ! messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join sentence = I18n.t("errors.messages.not_saved", :count => resource.errors.count, :resource => resource.class.model_name.human.downcase) ! html = <<-HTML <div id="error_explanation" class="alert alert-danger fade in"> <h4>#{sentence}</h4> <ul>#{messages}</ul> </div> HTML ! html.html_safe end end
  10. Helpers Mix HTML/Ruby code module DeviseHelper def devise_error_messages! return ""

    if resource.errors.empty? ! messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join sentence = I18n.t("errors.messages.not_saved", :count => resource.errors.count, :resource => resource.class.model_name.human.downcase) ! html = <<-HTML <div id="error_explanation" class="alert alert-danger fade in"> <h4>#{sentence}</h4> <ul>#{messages}</ul> </div> HTML ! html.html_safe end end
  11. Helpers - Potential Solutions Draper adds an object-oriented layer of

    presentation logic to your Rails application. Without Draper, this functionality might have been tangled up in procedural helpers or adding bulk to your models. With Draper decorators, you can wrap your models with presentation-related logic to organise - and test - this layer of your app much more effectively.
  12. Helpers - Potential Solutions Cells allow you to encapsulate parts

    of your UI into components into view models. View models, or cells, are simple ruby classes that can render templates.
  13. Concerns ! ! ! "Concerns are also a helpful way

    of extracting a slice of model that doesn’t seem part of its essence (what is and isn’t in the essence of a model is a fuzzy line and a longer discussion) without going full-bore Single Responsibility Principle and running the risk of ballooning your object inventory." - DHH Why we should use concerns?
  14. Concerns Why this can be Bad? Even there are a

    lot of posts saying Concerns is good idea...
  15. Concerns • Syntactic Sugar - for include/extend // Add complexity

    to Ruby's mixins • Add Dependency and Hide complexity • Harder to navigate in the codebase
  16. - app/ - controllers/ - accounts_controller.rb - interactions/ - accounts/

    - create_account.rb - destroy_account.rb - find_account.rb - list_accounts.rb - update_account.rb - models/ - account.rb - views/ - account/ - edit.html.erb - index.html.erb - new.html.erb - show.html.erb
  17. # GET /accounts def index @accounts = ListAccounts.run! end class

    ListAccounts < ActiveInteraction::Base def execute Account.not_deleted.order(last_name: :asc, first_name: :asc) end end Controller Interaction
  18. # GET /accounts/:id def show @account = find_account! end !

    private ! def find_account! outcome = FindAccount.run(params) ! if outcome.valid? outcome.result else fail ActiveRecord::RecordNotFound, outcome.errors.full_messages.to_sentence end end Controller
  19. class FindAccount < ActiveInteraction::Base integer :id ! def execute account

    = Account.not_deleted.find_by_id(id) ! if account account else errors.add(:id, 'does not exist') end end end Interaction
  20. References • https://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns • https://signalvnoise.com/posts/1108-what-belongs-in-a-helper-method • http://www.imdb.com/title/tt0086190/quotes • http://nicksda.apotomo.de/2010/11/lets-write-a-reusable-sidebar-component-in-rails-3/ •

    https://github.com/apotonick/cells • https://github.com/drapergem/draper • http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/ • http://brewhouse.io/blog/2014/04/30/gourmet-service-objects.html • https://github.com/orgsync/active_interaction • https://en.wikipedia.org/wiki/Single_responsibility_principle#cite_note-1