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

Ruby on Rails - The Single Engineer Framework

Radoslav Stankov
July 14, 2024
230

Ruby on Rails - The Single Engineer Framework

Radoslav Stankov

July 14, 2024
Tweet

Transcript

  1. !

  2. I began my web development career using Flash, PHP, and

    JavaScript at an agency in Dobrich in 2002.
  3. Careers in tech are long, and technology trends come and

    go. You won't be able to have a meaningful career working with a single technology your whole career.
  4. - one developer (me) $ - management portal % -

    implement a mobile app & - for iOS ' / Android (
  5. Building mapping ) Mobile app & Issue tracker * Employees

    + Bulletin board , Notifications - Taxation . Contacts / Omni search 0 Reporting 1 Printing 2 Bookkeeping 3 Voting 4 Financials 5 Homebook 6 Debtors 7 Bulk operations ⚙ Messaging 9 Calendar : Funds ; ePay / EasyPay < Bank imports = Invoicing > Warranty Issues ?
 Technicians @
 Individual accounts A Business accounts ) Audit logs B
 Archiving C Trials D Demo E
 I18n F G H
 Marketing site I
  6. Ruby on Rails and its ecosystem enabled me to develop

    Angry Building single-handedly. It felt like having a cheat code.
  7. Ruby Ruby is an interactive, object- oriented programming language. Its

    motto is: "Optimized for programmer happiness"
  8. Variables a = 1 # Number b = "string" #

    String c = [1, 2, 3, 4] # Array d = { key: 'value' } # Hash
  9. Everything is an object person.name "string".size array.empty? array[0] == array.first

    array[1] == array.second array[array.size - 1] == array.last 1.day.ago 1.day.ago - 2.hours
  10. Blocks [1,2,3,4].each { |value| puts value } # => [1,

    2, 3, 4] [1,2,3,4].map { |value| value * value } # => [1, 4, 9, 16] [1,2,3,4].reduce { |a, b| a + b } # => 10
  11. Blocks [1,2,3,4].each { puts _1 } # => [1, 2,

    3, 4] [1,2,3,4].map { _1 * _1 } # => [1, 4, 9, 16] [1,2,3,4].reduce { _1 + _1 } # => 10
  12. Expressions def explain_number(value) if value % 2 result = 'even'

    else result = 'odd' end return result end
  13. class Person def initialize(first_name, last_name) @first_name = first_name @last_name =

    last_name end def first_name @first_name end def first_name=(value) @first_name = value end Classes
  14. end def first_name=(value) @first_name = value end def last_name @last_name

    end def last_name=(value) @last_name = value end def full_name "#{first_name} + #{last_name}" end end Classes
  15. Classes class Person attr_reader :first_name, :last_name attr_writer :first_name, :last_name def

    initialize(first_name, last_name) @first_name = first_name @last_name = last_name end def full_name "#{first_name} + #{last_name}" end end
  16. Classes class Person attr_accessor :first_name, :last_name def initialize(first_name, last_name) @first_name

    = first_name @last_name = last_name end def full_name "#{first_name} + #{last_name}" end end
  17. R Nothing is special S Everything is an object T

    No definitions, just executions U Cool syntax V Meta programming
  18. Open classes class Array def first self[0] end def second

    self[1] end end array = [1, 2, 3, 4] array.first # 1 array.second # 2
  19. class MyClass puts "I'll be executed" unless RUBY_VERSION >= "3.3.3"


    puts "I'll be executed after ruby 3.3.3" def some_method # ... code end end end No definitions, just executions
  20. Meta programming class Person def self.attr_accessor(attribute) define_method(attribute) do instance_variable_get :"@#{attribute}"

    end define_method(:"#{attribute}=") do |value| instance_variable_set :"@#{attribute}", value end end end
  21. Meta programming class Person def self.attr_accessor(*attributes) attributes.each do |attribute| define_method(attribute)

    do instance_variable_get :"@#{attribute}" end define_method(:"#{attribute}=") do |value| instance_variable_set :"@#{attribute}", value end end end end
  22. W Model View Controller (MVC) X Batteries included Y Convention

    over configuration Z Extendible platform
  23. ActiveSupport - utilities ActiveModel - base model & validations ActiveRecord

    - object relation mapper (ORM) ActiveJob - background job processing ActiveStorage - file uploads ActionController - Controller from MVC ActionView - View from MVC ActionMailer - Sending emails ActionMailbox - Receiving & processing emails ActionCable - Web Socket & real time ActionText - Rich text editing Propshaft - assets delivery I18n - internalization X Batteries included
  24. db/migrate/[...]_create_posts.rb class CreatePosts < ActiveRecord::Migration[7.1] def change create_table :posts do

    |t| t.string :title, null: false t.text :content, null: false t.timestamps end end end
  25. Rails.application.routes.draw do resources :posts # Define your application routes per

    the DSL in # https://guides.rubyonrails.org/routing.html # Reveal health status on /up that returns 200 # if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to # verify that the app is live. get "up" => "rails/health#show", as: :rails_health_check # Defines the root path route ("/") # root "posts#index" end config/routes.rb
  26. class PostsController < ApplicationController # GET /posts def index @posts

    = Post.all end # GET /posts/1 def show @post = Post.find(params[:id]) end # GET /posts/new def new @post = Post.new end # GET /posts/1/edit def edit @post = Post.find(params[:id]) end # POST /posts def create app/controllers/posts_controller.rb
  27. # POST /posts def create @post = Post.new(post_params) if @post.save

    redirect_to post_url(@post), notice: "Post was successfully cr else render :new, status: :unprocessable_entity end end # PATCH/PUT /posts/1 def update @post = Post.find(params[:id]) if @post.update(post_params) redirect_to post_url(@post), notice: "Post was successfully up else render :edit, status: :unprocessable_entity end end # DELETE /posts/1 app/controllers/posts_controller.rb
  28. if @post.update(post_params) redirect_to post_url(@post), notice: "Post was successfully up else

    render :edit, status: :unprocessable_entity end end # DELETE /posts/1 def destroy @post = Post.find(params[:id]) @post.destroy! redirect_to posts_url, notice: "Post was successfully destroyed. end private def post_params params.require(:post).permit(:title, :content) end end app/controllers/posts_controller.rb
  29. <p style="color: green"><%= notice %></p> <h1>Posts</h1> <div id="posts"> <% @posts.each

    do |post| %> <%= render post %> <p> <%= link_to "Show this post", post %> </p> <% end %> </div> <%= link_to "New post", new_post_path %> app/views/posts/index.html.erb
  30. <%= form_with(model: post) do |form| %> <% if post.errors.any? %>

    <div style="color: red"> <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from bei <ul> <% post.errors.each do |error| %> <li><%= error.full_message %></li> <% end %> </ul> </div> <% end %> <div> <%= form.label :title, style: "display: block" %> <%= form.text_field :title %> </div> <div> <%= form.label :content, style: "display: block" %> <%= form.text_area :content %> </div> <div> <%= form.submit %> </div> <% end %> app/views/posts/_form.html.erb
  31. class Post < ApplicationRecord validates :title, presence: true validates :content,

    presence: true has_rich_text :content end app/models/post.rb
  32. <%= form_with(model: post) do |form| %> <% if post.errors.any? %>

    <div style="color: red"> <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from bei <ul> <% post.errors.each do |error| %> <li><%= error.full_message %></li> <% end %> </ul> </div> <% end %> <div> <%= form.label :title, style: "display: block" %> <%= form.text_field :title %> </div> <div> <%= form.label :content, style: "display: block" %> <%= form.rich_text_area :content %> </div> <div> <%= form.submit %> </div> <% end %> app/views/posts/_form.html.erb