{"id":329410,"date":"2022-02-11T09:00:15","date_gmt":"2022-02-11T09:00:15","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=329410"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=329410","title":{"rendered":"<span>\u0422\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430: \u043a\u0430\u043a\u043e\u0432 Elixir \u043d\u0430 \u0432\u043a\u0443\u0441 \u043f\u043e\u0441\u043b\u0435 Ruby<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"485\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/917\/50a\/752\/91750a7527d0d54b16c83138f9526ad9.png\" data-width=\"1221\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e<\/h2>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041d\u0430\u0442\u0430\u043b\u044c\u044f. \u0412 \u041a\u0430\u0440\u0443\u043d\u0435 \u044f \u043f\u0438\u0448\u0443 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043d\u0430 Elixir. <\/p>\n<p>\u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u043d\u0430 Elixir. \u0414\u043e \u044d\u0442\u043e\u0433\u043e \u044f \u043f\u0438\u0441\u0430\u043b\u0430 \u043d\u0430 Ruby. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0432\u0435\u0436\u0435\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0425\u0430\u0431\u0440 \u041a\u0430\u0440\u044c\u0435\u0440\u044b \u043f\u043e \u0437\u0430\u0440\u043f\u043b\u0430\u0442\u0430\u043c, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u2014 \u0437\u0430\u0440\u043f\u043b\u0430\u0442\u044b \u0440\u0443\u0431\u0438\u0441\u0442\u043e\u0432 \u0440\u0430\u0441\u0442\u0443\u0442, \u0430 Elixir \u0442\u0430\u043c \u043d\u0435\u0442. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043b\u044e\u0434\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u0438\u0441\u044c \u0441 Elixir \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043d\u0430 Ruby. \u042f \u0441\u0447\u0438\u0442\u0430\u044e, \u0447\u0442\u043e \u043d\u0430 \u044d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u0432\u0445\u043e\u0434 \u0432 \u044f\u0437\u044b\u043a. Elixir \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0439, \u043d\u043e \u0432 \u043f\u0435\u0440\u0432\u044b\u0435 \u043c\u0435\u0441\u044f\u0446\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0430 \u0441 \u043d\u0438\u043c \u043c\u043d\u0435 \u0441\u0430\u043c\u043e\u0439 \u0442\u0430\u043a \u043d\u0435 \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c. \u041d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0439, \u0447\u0442\u043e \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u043d\u0430\u0437\u0430\u0434. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0438 <s>\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430<\/s> \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430.<\/p>\n<blockquote>\n<p><strong>Elixir<\/strong> is a functional programming language which looks <em><u>similar<\/u><\/em> to <strong>Ruby<\/strong>.<\/p>\n<\/blockquote>\n<p>\u0412 IT \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0440\u0443\u0431\u0438\u0441\u0442\u044b \u043b\u0435\u0433\u043a\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 Elixir. \u0415\u0449\u0451 \u0431\u044b \u2014 \u0441\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u044c \u044f\u0437\u044b\u043a\u0430 Jose Walim \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0440\u0443\u0431\u0438\u0441\u0442. \u041d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0443\u0431\u0438\u0441\u0442, \u0430 core \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a Ruby on Rails. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e Elixir \u2014 \u044d\u0442\u043e Ruby \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u043a\u0430\u0447\u043a\u0438. \u0422\u0435\u0431\u0435 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a \u0436\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\/\u0431\u044b\u0441\u0442\u0440\u043e\/\u043a\u043b\u0430\u0441\u0441\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u043d\u0451\u043c, \u043f\u043b\u044e\u0441\u043e\u043c \u0438\u0434\u0451\u0442 \u0432\u0441\u044f \u043c\u043e\u0449\u044c Erlang\u2019\u0430. \u041c\u043d\u0435 \u0432 \u0441\u0432\u043e\u0451 \u0432\u0440\u0435\u043c\u044f \u043e\u0447\u0435\u043d\u044c \u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f Ruby. \u0418 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 Elixir \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043c\u0430\u043d\u0447\u0438\u0432\u043e\u0439 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u043e\u0439.<\/p>\n<h2>Ruby |> Elixir\u00a0<\/h2>\n<p>\u0418\u0437\u0443\u0447\u0430\u044f \u043d\u043e\u0432\u0443\u044e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e, \u044f \u0441\u0442\u0440\u0435\u043c\u043b\u044e\u0441\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438. \u0414\u0430, \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442 \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439. \u041e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c. \u0418 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0448\u0442\u0443\u043a\u0438.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0431\u0435\u0433\u043b\u043e\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0430 \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u0432 \u043c\u043e\u0435\u0439 \u0433\u043e\u043b\u043e\u0432\u0435 \u0431\u044b\u043b \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043b\u0430\u043d \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u044f\u0437\u044b\u043a\u0430\u043c\u0438. \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u201c|>\u201d \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435.<\/p>\n<pre><code class=\"erlang\">Ruby |> remove_OOP() |> add_some_functions() |> save_TDD() |> add_OTP() |> save_syntactic_sugar() {:ok, Elixir}<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0448\u0430\u0433\u0438. \u0417\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e \u041e\u041e\u041f. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0411\u0443\u0434\u0435\u0442 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435. \u041d\u043e \u0442\u0435\u0441\u0442\u044b \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u044f\u043b. \u0415\u0441\u0442\u044c \u0446\u0435\u043b\u0430\u044f \u043d\u043e\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c Open Telecom Platform. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c VS Code.<\/p>\n<pre><code class=\"ruby\">%{a: 1} # map in Elixir {a: 1} # hash in Ruby  # Lists [1, 2, true, 3] # Elixir, Ruby # Concatenate lists [1, 2, true, 3] ++ [5, 7] # Elixir [1, 2, true, 3] + [5, 7]  # Ruby  # Calling function\/method String.reverce(\"hello\") # Elixir \"hello\".reverse         # Ruby  # An anonymous function fn(x) -> x * x end # ELixir -> x {x * x} # lambda in Ruby  # Using each Enum.each([1, 2], &amp;(IO.puts &amp;1)) # Elixir [1, 2].each { |i| puts i }       # Ruby  # Defining a function in Elixir def hello do   \"result\" end # Defining a method in Ruby def hello   \"result\" end  # Defining a module in Elixir defmodule Example do end # Defining a module in Ruby module Example end<\/code><\/pre>\n<p>\u041e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0435. \u041f\u043e\u0434\u0443\u043c\u0430\u0435\u0448\u044c: \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0438\u043c\u044f \u043c\u043e\u0434\u0443\u043b\u044f.\u00a0<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0433\u043e\u0434 \u0432\u0438\u0441\u043e\u043a\u043e\u0441\u043d\u044b\u043c.\u00a0<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">class Year  def self.leap?(year)    @year = year    div_by?(4) &amp;&amp; ( !div_by?(100) || div_by?(400) )  end    def self.div_by?(number)    @year % number == 0  end end<\/code><\/pre>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">defmodule Year do  def leap?(year) do    div_by?(year, 4) &amp;&amp; ( !div_by?(year, 100) || div_by?(year, 400) )  end   def div_by?(year, number) do    rem(year, number) == 0  end end<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0433\u043e\u0434. \u041e\u0441\u0442\u0430\u0442\u043e\u043a \u043e\u0442 \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u041d\u0430\u0434\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c do \u043f\u0440\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.\u00a0\u00a0<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0438 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Elixir. \u041e\u043d \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c. \u0414\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0442\u044b \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u043e\u0432 \u044f \u0431\u0435\u0440\u0443 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 Ruby minitest., \u0442.\u043a. \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b Elixir \u0443 \u043d\u0430\u0441 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 Test Driven Development. \u0411\u044b\u0432\u0448\u0438\u0435 \u0440\u0443\u0431\u0438\u0441\u0442\u044b, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430\u043a\u043b\u0435\u043f\u0430\u043b\u0438 \u0443\u0436\u0435 \u0441\u0435\u0431\u0435 <a href=\"https:\/\/github.com\/antonmi\/espec\">espec<\/a>. \u041e\u043d, \u043f\u0440\u0430\u0432\u0434\u0430, \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u043f\u0440\u0438\u0436\u0438\u043b\u0441\u044f. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u2014 \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e minitest \u0432\u044b \u0445\u043e\u0442\u044c \u0440\u0430\u0437 \u0432\u0438\u0434\u0435\u043b\u0438. \u0418 \u043f\u043e\u043c\u043d\u0438\u043c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">require 'minitest\/autorun' require_relative 'leap'  class YearTest &lt; Minitest::Test  def test_year_not_divisible_by_4_common_year    # skip    refute Year.leap?(2015), \"Expected 'false', 2015 is not a leap year.\"  end   def test_year_divisible_by_4_not_divisible_by_100    assert Year.leap?(1996), \"Expected 'true', 1996 is a leap year.\"  end   def test_year_divisible_by_100_not_divisible_by_400    refute Year.leap?(2100), \"Expected 'false', 2100 is not a leap year.\"  end   def test_year_divisible_by_400    assert Year.leap?(2000), \"Expected 'true', 2000 is a leap year.\"  end   def test_year_divisible_by_200_not_divisible_by_400    # skip    refute Year.leap?(1800), \"Expected 'false', 1800 is not a leap year.\"  end end<\/code><\/pre>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">Code.load_file(\"leap.exs\", __DIR__)  ExUnit.start() ExUnit.configure(exclude: :pending, trace: true)  defmodule LeapTest do  use ExUnit.Case   test \"2015 year not divisible by 4\" do    refute Year.leap?(2015)  end   # @tag :pending  test \"1996 year divisible by 4 not divisible by 100 leap year\" do    assert Year.leap?(1996)  end   test \"2100 year divisible by 100 not divisible by 400\" do    refute Year.leap?(2100)  end   test \"2000 year divisible by 400 leap year\" do    assert Year.leap?(2000)  end   test \"1800 year divisible by 200 not divisible by 400\" do    refute Year.leap?(1800)  end end<\/code><\/pre>\n<p>\u0421\u043d\u043e\u0432\u0430 \u043e\u0442\u043b\u0438\u0447\u0438\u044f, \u043a\u0440\u043e\u043c\u0435 \u0443\u0436\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445, \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0432\u0435\u043b\u0438\u043a\u0438. \u0421\u043a\u0438\u043f\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0442\u044d\u0433. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043a\u0430\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439: \u201cexclude: :pending\u201d. <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u044b\u0441\u043b\u044c\u2026<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/a41\/836\/710\/a41836710920b370bc25377ff6f18b3d.jpeg\" alt=\"Hey, Brain! I can write on Elixir?! \" title=\"Hey, Brain! I can write on Elixir?! \" width=\"1012\" height=\"675\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a41\/836\/710\/a41836710920b370bc25377ff6f18b3d.jpeg\" data-blurred=\"true\"\/><figcaption>Hey, Brain! I can write on Elixir?! <\/figcaption><\/figure>\n<h2>Ruby on Rails |> Phoenix<\/h2>\n<p>\u0421 \u044f\u0437\u044b\u043a\u043e\u043c \u0431\u044b\u043b\u043e \u043b\u0435\u0433\u043a\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0442\u0430\u043c \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438. \u0412 \u043a\u0440\u0430\u0442\u043a\u043e\u043c \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u044f \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u044d\u0442\u043e \u0441\u043e\u0431\u0440\u0430\u043b\u0430 \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435:<\/p>\n<pre><code>Rails controller == Phoenix controller (in Context) Rails model =~ Ecto (Schema + Repo + Query + ...) Rails view (template) =~ Phoenix view + template Rails serializer == Phoenix view Rails seeds\/tasks =~ Phoenix seeds\/tasks Rails migrations =~ Ecto migrations Rails console != Phoenix console<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430\u0436\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f.<\/p>\n<h3>\u041c\u0438\u0433\u0440\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f\u043c\u0438.<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">rails db:migrate rails db:rollback rails db:rollback STEP=2  rails db:migrate VERSION=20181213084911  rails db:migrate:redo VERSION=20181213084911 rails db:migrate:up VERSION=20181213084911 rails db:migrate:down VERSION=20181213084911<\/code><\/pre>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">mix ecto.migrate mix ecto.migrate -r Custom.Repo mix ecto.migrate -n 3  mix ecto.rollback mix ecto.rollback --step 2  mix ecto.migrate -to 20181213084911 mix ecto.rollback -to 20181213084911  # What?!<\/code><\/pre>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0433\u043e\u0432. \u041d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 Repo. \u041d\u0435\u043b\u044c\u0437\u044f \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c \u0438\u043b\u0438 \u043d\u0430\u043a\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 \u0442\u0430\u0441\u043a\u0438. \u0422\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0447\u043a\u0443 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439, \u0434\u0440\u0443\u0433 \u0437\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u2014 \u0434\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043a\u043e\u043f\u0430\u0442\u044c\u0441\u044f \u0432 API Ecto, \u0442\u043e \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043c\u043e\u0436\u043d\u043e&#8230;<\/p>\n<pre><code class=\"erlang\">Ecto.Migrator.with_repo(your_repo, &amp;Ecto.Migrator.run(&amp;1, :down, to: version))<\/code><\/pre>\n<p>\u0427\u0442\u043e \u044d\u0442\u043e \u0437\u0430 Repo, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439<\/h3>\n<p>\u042d\u0442\u043e \u0432\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0449\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0438\u0432\u0430\u0435\u0442 \u0438\u0437 \u043a\u043e\u043b\u0435\u0438. \u041f\u0435\u0440\u0432\u0430\u044f \u2014 \u0441\u0430\u043c\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0430. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u0430\u043a \u043c\u0438\u0440 \u0432\u0435\u0431 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u043f\u0438\u0442\u0430\u043d \u041e\u041e\u041f, \u0442\u0430\u043a \u0438 \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0432 \u043c\u0438\u0440\u0435 \u041e\u041e\u041f \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 ORM. \u0412 Rails \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0441 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u0438\u0437 \u0411\u0414 \u043a\u0430\u043a \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Active Record. \u0417\u0430\u0431\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435. \u041f\u0440\u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c Elixir \u043c\u044b \u0443\u0436\u0435 \u0443\u0442\u0440\u0430\u0442\u0438\u043b\u0438 \u0447\u0430\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0437\u0433\u043b\u044f\u0434\u0430 \u043d\u0430 \u043c\u0438\u0440. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432\u0440\u0435\u043c\u044f \u0443\u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u043e \u043a\u043e\u043d\u0446\u0430 (\u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438). \u041d\u0430 \u0441\u0446\u0435\u043d\u0443 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 Ecto. \u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435: Ecto \u2014 \u044d\u0442\u043e data mapper + query builder DSL.<\/p>\n<pre><code>Active Record is ORM, gives us:   - models and their data - associations between models - models validation  - database operations in an object-oriented style Ecto differs from other ORMs:   - schemas and their data - associations between schemas - changeset with validations  - database operations in functional style with Ecto modules (Repo, Query, etc.)<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c \u0432 \u0441\u0445\u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0410\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438 \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0434\u0435\u043b\u0438\u0441\u044c. \u0427\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0438\u0437 \u043a\u0430\u043a\u0438\u0445 \u043f\u043e\u043b\u0435\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0430\u0434\u043e \u043a\u0443\u0434\u0430-\u0442\u043e \u0445\u043e\u0434\u0438\u0442\u044c. \u0421\u0445\u0435\u043c\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0415\u0441\u0442\u044c \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0439 \u043d\u044e\u0430\u043d\u0441: \u0441\u0445\u0435\u043c\u0430 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u043b\u044f. \u0421\u0445\u0435\u043c\u043e\u0439 \u043c\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0417\u0430\u0447\u0435\u043c? \u042f \u043c\u043e\u0433\u0443 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:\u00a0<\/p>\n<p>1. \u041a\u0430\u043a\u043e\u0435-\u0442\u043e \u043f\u043e\u043b\u0435 \u0441\u0442\u0430\u043b\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043c\u0435\u043d\u044f\u0442\u044c, \u043d\u043e \u043e\u043d\u043e \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438\/\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0441\u0445\u0435\u043c\u044b, \u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0411\u0414.\u00a0<\/p>\n<p>2. \u0420\u0430\u0437\u043d\u044b\u0435 \u043d\u0430\u0431\u043e\u0440\u044b \u043f\u043e\u043b\u0435\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u0432. \u0420\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043e\u0431\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430\u0436\u0443\u0442\u0441\u044f \u0441\u0438\u043d\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u2014 \u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0430 \u0434\u043b\u044f \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0439\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445.\u00a0<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">class OnlineTracking &lt; ActiveRecord::Base  belongs_to :startup  belongs_to :expert, class_name: 'User'  has_one :expert_startup_rate, class_name: 'ExpertAnketa::StartupRate', dependent: :destroy  has_many :slots, class_name: 'OnlineTracking::Slot', foreign_key: :online_tracking_id   validates :startup_id, presence: true  validates :start_at, presence: true  validates :weeks, presence: true, numericality: { only_integer: true }   enum pause_status: {    disabled: 0, # \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435    date_changed: 1, # \u043f\u0435\u0440\u0435\u043d\u043e\u0441  }   after_create :make_anketas  after_update :update_startup_leads, if: Proc.new { |ot| ot.finished_at.present? || ot.deleted? }<\/code><\/pre>\n<p>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0445\u0435\u043c\u044b, \u043d\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043d\u0438\u0445 changeset (Ecto.Changeset). \u0427\u0442\u043e \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442? Changeset \u2014\u00a0\u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u0435\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043e\u0442 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043e\u0442 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430\u2026 \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u044f \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u041d\u0415 \u0447\u0435\u0440\u0435\u0437 changeset. \u0425\u043e\u0442\u044f \u0441\u0442\u043e\u0438\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0443: \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f Repo.update_all\/3, \u043b\u0438\u0431\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0447\u0438\u0441\u0442\u044b\u0439 SQL-\u0437\u0430\u043f\u0440\u043e\u0441. \u041d\u043e \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0439\u0442\u0438 \u0432 \u043e\u0431\u0445\u043e\u0434.\u00a0<\/p>\n<p>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c \u2014 \u043d\u043e \u0440\u043e\u0432\u043d\u043e \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0443\u0437\u043d\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u0443 \u0441\u0445\u0435\u043c\u044b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e changeset\u2019\u043e\u0432. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0447\u0435\u043c\u0443 \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u2014 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043c\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u0435\u0439, \u0430 \u043f\u0440\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u043e\u0434\u0440\u044f\u0434. \u0414\u043b\u044f \u0440\u044f\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u043b\u0435\u0439 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432\u0441\u0435\u0433\u0434\u0430 (\u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0440\u043e\u043b\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440). \u0421\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c \u2014 \u0441\u0442\u043e\u043b\u044c\u043a\u043e changeset\u2019\u043e\u0432 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f. \u0421\u043c\u0435\u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u044f, \u0441\u043c\u0435\u043d\u0430 email, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u044f, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u2014 \u0440\u0430\u0437\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b, \u0440\u0430\u0437\u043d\u044b\u0435 changeset\u2019\u044b. \u0415\u0449\u0451 \u043e\u0434\u043d\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 changeset\u2019\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0443\u0436\u043d\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438. \u0422\u0435. \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0430\u0441\u0430\u044e\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u2014 \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0442\u0438\u043f\u0438\u0447\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c ActiveRecord \u043f\u043e \u043c\u0435\u0440\u0435 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0430\u0433\u0440\u043e\u043c\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0438 callback\u2019\u043e\u0432. \u0412 \u044d\u0442\u043e\u043c \u0445\u0430\u043e\u0441\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f. \u041c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f: \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0432\u0430 \u0432\u0438\u0434\u0430 \u043d\u043e\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439, \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u0431\u0430\u043b\u043b\u044b, \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043b\u044f \u043e\u0442\u0447\u0451\u0442\u043e\u0432\u2026 <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a Phoenix \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e \u0441\u043b\u043e\u044f\u043c.<\/p>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">defmodule App.Accounts.User do   use Ecto.Schema   import Ecto.Changeset    alias Ecto.Changeset   alias App.Accounts.User   alias App.CompanyManagement.Employee   alias App.EmailType   alias App.Repo    @required [:email, :password]   @optional [:type]    schema \"users\" do     field :email, EmailType     field :password, :string, virtual: true     field :password_confirmation, :string, virtual: true     field :password_hash, :string     field :recovery_token, :string     field :refresh_token, :string     field :type, UserTypeEnum      has_one :employee, Employee      timestamps(type: :naive_datetime_usec)   end    @required_fields ~w(email)a   @optional_fields ~w()a    def changeset(%User{} = user, attrs) do     user     |> cast(attrs, @required_fields ++ @optional_fields)     |> validate_required(@required_fields)     |> unique_email()   end    def email_changeset(%User{} = user, attrs) do     user     |> cast(attrs, [:email])     |> unique_email()   end    def create_changeset(%User{} = user, attrs) do     user     |> cast(attrs, @required ++ @optional)     |> validate_required(@required)     |> unique_email()     |> unique_constraint(:id, name: :users_pkey)     |> validate_password(:password)     |> put_pass_hash()   end       def recovery_changeset(%User{} = user, %{\"password\" => password}) do     user     |> change(%{recovery_token: nil, refresh_token: nil, password: password})     |> validate_password(:password)     |> put_pass_hash()   end<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e changeset\u2019\u0430 \u0438 \u0441\u0445\u0435\u043c\u044b User \u0434\u043b\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f Repo. \u041c\u043e\u0434\u0443\u043b\u044c \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u2014 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0431\u0430\u0437\u043e\u0439.<\/p>\n<pre><code class=\"erlang\">defmodule App.Accounts.UserQueries do  alias App.Accounts.User  alias App.Repo   def create(attrs \\\\ %{}) do    %User{}    |> User.create_changeset(attrs)    |> Repo.insert()  end   def update(%User{} = user, attrs) do    user    |> User.changeset(attrs)    |> Repo.update()  end   def delete(%User{} = user) do    Repo.delete(user)  end   def update_refresh_token(%User{} = user, refresh_token) do    user    |> User.refresh_token_changeset(%{refresh_token: refresh_token})    |> Repo.update()  end end<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0445\u0435\u043c\u044b \u043d\u0435\u0442. \u0414\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u044d\u0442\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u0421 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0430\u0441\u044c. \u0412 Rails \u0443 \u043d\u0430\u0441 \u0441\u043a\u043e\u0443\u043f\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0447\u043a\u0443 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438.\u00a0<\/p>\n<pre><code class=\"ruby\">scope :finished, -> { where('finished_at is not null') } scope :active, -> { where(active: true) } scope :recommended, -> { where(status: OnlineTracking.statuses[:recommended]) } scope :by_start_date, -> (date_from, date_to) { where('start_at BETWEEN ? AND ?', date_from, date_to) }<\/code><\/pre>\n<p>Ecto \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u043d\u0430\u043c Repo, \u0430 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u2014 DSL \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c Ecto.Query.<\/p>\n<pre><code class=\"erlang\">defmodule App.Catalog.HouseQueries do  import Ecto.Query, warn: false   alias App.Repo  alias App.Catalog.House  alias App.Catalog.ResidentialComplex   def get(id), do: Repo.get(House, id)   def list(params, search_params \\\\ nil) do    list_query()    |> filter_city(search_params[:city_id])    |> Repo.paginate(params)  end   defp list_query() do    from h in House,      where: is_nil(h.archived_at),      preload: ^preload_list()  end   defp filter_city(query, nil), do: query  defp filter_city(query, city_id) do    from i in query,      join: r in ResidentialComplex,      where: i.residential_complex_id == r.id,      where: r.city_id == ^city_id  end<\/code><\/pre>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c SQL \u0435\u0441\u0442\u044c \u0432 \u043e\u0431\u043e\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0432 Elixir \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0451 \u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438? \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f\u2026\u00a0<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">class Book &lt; ApplicationRecord  belongs_to :author, counter_cache: :count_of_books end<\/code><\/pre>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">defmodule App.Catalog.ResidentialComplex  schema \"residential_complexs\" do    field :houses_count, :integer, default: 0    has_many :houses, Catalog.House end  defmodule App.Catalog.House do  # schema   def changeset(house, attrs) do    house    |> cast(attrs, @required ++ @optional)    |> validate_required(@required)    |> prepare_changes(&amp;complex_houses_count\/1)    |> assoc_constraint(:residential_complex)  end   defp complex_houses_count(changeset) do    if complex_id = get_change(changeset, :residential_complex_id) do      if changeset.action == :update do        prev_complex_id = changeset.data.residential_complex_id        query = from Catalog.ResidentialComplex, where: [id: ^prev_complex_id]        changeset.repo.update_all(query, inc: [houses_count: -1])      end      query = from Catalog.ResidentialComplex, where: [id: ^complex_id]      changeset.repo.update_all(query, inc: [houses_count: 1])    end    changeset  end<\/code><\/pre>\n<p>What?!<\/p>\n<h3>\u041a\u043e\u043d\u0441\u043e\u043b\u044c<\/h3>\n<p>Ruby \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 irb, Elixir \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e iex. \u0418 \u044d\u0442\u043e \u0431\u044b\u043b \u043c\u043e\u0439 \u0442\u043e\u043f-1 \u0432 \u043b\u0438\u0441\u0442\u0435 \u0448\u043e\u043a\u0430 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043d\u0441\u043e\u043b\u044c.<\/p>\n<p>rails c<\/p>\n<pre><code class=\"ruby\">> OnlineTracking.find(409).update(active: false) => true > ActiveRecord::Migration.drop_table(:experts_groups) => true > OnlineTracking.last > OnlineTracking.startup.user.name<\/code><\/pre>\n<p>iex -S mix<\/p>\n<pre><code class=\"erlang\">> Repo.get(ResidentialComplex, 1) |> Ecto.Changeset.change(houses_count: 0) |> Repo.update() ** (UndefinedFunctionError) function Repo.get\/2 is undefined (module Repo is not available)     Repo.get(ResidentialComplex, 1) > alias App.Repo App.Repo > Repo.get(ResidentialComplex, 1) |> Ecto.Changeset.change(houses_count: 0) |> Repo.update() ** (Protocol.UndefinedError) protocol Ecto.Queryable not implemented for ResidentialComplex, the given module does not exist.  This protocol is implemented for: Atom, BitString, Ecto.Query, Ecto.SubQuery, Tuple > alias App.Catalog.ResidentialComplex App.Catalog.ResidentialComplex > Repo.get(ResidentialComplex, 1) |> Ecto.Changeset.change(houses_count: 0) |> Repo.update() {:ok, %App.Catalog.ResidentialComplex} > ResidentialComplex |> last() |> Repo.one()<\/code><\/pre>\n<p>\u0410 \u0432\u0435\u0434\u044c \u044f \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0435 \u0432\u0435\u0449\u0438: \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u0434\u043d\u043e \u043f\u043e\u043b\u0435, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0434\u043d\u0443 \u0437\u0430\u043f\u0438\u0441\u044c.<\/p>\n<p>\u041a\u0430\u043a \u0441 \u044d\u0442\u0438\u043c \u0436\u0438\u0442\u044c? \u041f\u0440\u0438\u043d\u044f\u0442\u044c \u043d\u0430 \u0432\u0435\u0440\u0443:<\/p>\n<p>Rails \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0442\u0435\u0431\u0435: \u0434\u0430, \u0434\u0435\u043b\u0430\u0439 \u0447\u0442\u043e \u0445\u043e\u0447\u0435\u0448\u044c.\u00a0<\/p>\n<p>\u0425\u043e\u0447\u0435\u0448\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043d\u0430 \u0436\u0438\u0432\u0443\u044e \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c? \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430.<\/p>\n<p>\u0425\u043e\u0447\u0435\u0448\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u043d\u0430 \u043f\u0440\u043e\u0434\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438? \u0427\u0435\u0433\u043e \u0431\u044b \u0438 \u043d\u0435\u0442, \u043e\u0434\u0438\u043d update.<\/p>\n<p>IEX \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0442\u0435\u0431\u0435: \u0447\u0442\u0438 \u0437\u0430\u043f\u043e\u0432\u0435\u0434\u0438! \u041f\u043e\u043a\u0430 \u043d\u0435 \u0432\u044b\u0443\u0447\u0438\u0448\u044c, \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438.<\/p>\n<p>\u0417\u0430\u043f\u043e\u0432\u0435\u0434\u0438:<\/p>\n<ul>\n<li>\n<p>\u041a\u0442\u043e \u0442\u044b, \u0447\u0442\u043e \u0442\u0435\u0431\u0435 \u043d\u0443\u0436\u043d\u043e? \u042f \u043d\u0438\u0447\u0435\u0433\u043e \u043e \u0442\u0435\u0431\u0435 \u043d\u0435 \u0437\u043d\u0430\u044e. \u041b\u044e\u0431\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0447\u0435\u0448\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0437\u0432\u0430\u0442\u044c (\u0447\u0435\u0440\u0435\u0437 alias, import). \u041b\u0438\u0431\u043e \u043c\u043e\u0436\u043d\u043e \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b .iex.exs \u0438 \u0442\u0430\u043c \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u043e\u0437\u0432\u0430\u0442\u044c \u0437\u0430\u0440\u0430\u043d\u0435\u0435.\u00a0<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0431\u0430\u0437\u0443 \u0432\u0435\u0434\u0443\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0440\u043e\u0442. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0439 \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u043c\u043e\u0434\u0443\u043b\u0438 (Repo, Query, Changeset).<\/p>\n<\/li>\n<li>\n<p>\u041c\u044b \u043d\u0435 \u0434\u0451\u0440\u0433\u0430\u0435\u043c \u0442\u043e\u0432\u0430\u0440\u0438\u0449\u0435\u0439 \u0431\u0435\u0437 \u043d\u0443\u0436\u0434\u044b. \u041d\u0435\u043b\u044c\u0437\u044f \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0435\u0451 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 preload().<\/p>\n<\/li>\n<li>\n<p>\u0421\u043c\u043e\u0442\u0440\u0438 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u043f\u0438\u0448\u0435\u0448\u044c. \u041f\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043e\u0448\u0438\u0431\u043a\u0438 \u0431\u044b\u0432\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0442\u044b \u043e\u043f\u0435\u0447\u0430\u0442\u0430\u043b\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p>RTFM.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041e\u0448\u0438\u0431\u043a\u0438<\/h3>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u043a \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445. \u041f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u043e \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u043a\u043e\u0439.\u00a0<\/p>\n<pre><code class=\"erlang\">> alias App.Catalog.ResidentailComplex App.Catalog.ResidentailComplex > Repo.get(ResidentialComplex, 1)  ** (Protocol.UndefinedError) protocol Ecto.Queryable not implemented for ResidentialComplex, the given module does not exist.  This protocol is implemented for: Atom, BitString, Ecto.Query, Ecto.SubQuery, Tuple  defmodule AppWeb.Catalog.ResidentialComplexView do   def render(\"show.json\", residential_complex: complex) do      render_one(complex, ResidentialComplexView, \"residential_complex.json\")   end Request: GET \/api\/complexes\/2 ** (exit) an exception was raised:     ** (Phoenix.Template.UndefinedError) Could not render \"show.json\" for AppWeb.Catalog.ResidentialComplexView,  please define a matching clause for render\/2 or define a template at \"lib\/app_web\/templates\/catalog\/residential_complex\".  No templates were compiled for this module.<\/code><\/pre>\n<p>\u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044f \u043f\u043e\u0437\u0432\u0430\u043b\u0430 \u043c\u043e\u0434\u0443\u043b\u044c, \u043d\u043e \u043e\u0448\u0438\u0431\u043b\u0430\u0441\u044c \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438. \u0411\u0443\u043a\u0432\u044b \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u043b\u0430 \u043c\u0435\u0441\u0442\u0430\u043c\u0438. \u0410 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0430, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0443 \u2014 \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u0442\u0430\u043a\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f.\u00a0<\/p>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u044c\u044e\u0445\u0438. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u043e\u0439\u0434\u0451\u0442 \u0447\u0435\u0440\u0435\u0437 \u0432\u044c\u044e\u0445\u0443 \u0438\u0441\u043a\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d. \u0412\u043e \u0432\u044c\u044e\u0445\u0435 \u043c\u044b \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435. \u041c\u043e\u0436\u043d\u043e \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u0440\u0435\u0437\u0430\u0442\u044c \u0438\u043b\u0438 \u043a\u0430\u043a-\u0442\u043e \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c. \u041f\u043e \u043c\u043d\u0435, \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e. \u0412\u043e\u0442 \u044f \u0432\u0438\u0436\u0443 \u043e\u0448\u0438\u0431\u043a\u0443. \u0427\u0442\u043e \u0442\u0430\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e? \u0427\u0442\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435\u043b\u044c\u0437\u044f \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c json, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u044c\u044e\u0445\u0438 \u043c\u043e\u0435\u0439 \u043d\u0435\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 render. \u041d\u043e \u043e\u043d\u0430 \u0436\u0435 \u0435\u0441\u0442\u044c. \u0412\u044b \u0436\u0435 \u0435\u0451 \u0442\u043e\u0436\u0435 \u0432\u0438\u0434\u0438\u0442\u0435? \u0412\u044c\u044e\u0445\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, json \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e. \u042f \u0432 \u0441\u0432\u043e\u0451 \u0432\u0440\u0435\u043c\u044f \u0433\u043e\u043b\u043e\u0432\u0443 \u0441\u0435\u0431\u0435 \u0441\u043b\u043e\u043c\u0430\u043b\u0430, \u043f\u044b\u0442\u0430\u044f\u0441\u044c \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043d\u0435 \u0442\u0430\u043a.\u00a0<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/2e7\/989\/89b\/2e798989b683443bd04dc2e2c87555bc.jpeg\" alt=\"Brain, is the compiler our friend?\" title=\"Brain, is the compiler our friend?\" width=\"1280\" height=\"720\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2e7\/989\/89b\/2e798989b683443bd04dc2e2c87555bc.jpeg\" data-blurred=\"true\"\/><figcaption>Brain, is the compiler our friend?<\/figcaption><\/figure>\n<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0440\u0443\u0431\u0438\u0441\u0442\u0430\u043c \u0438 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044f\u043c \u044d\u043b\u0438\u043a\u0441\u0438\u0440\u0430 \u043d\u0430\u0439\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0443. \u0415\u0441\u043b\u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043d\u0430\u0439\u0434\u0451\u0442, \u043f\u043e\u0437\u0436\u0435 \u0441\u0430\u043c\u0430 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043d\u0430\u043f\u0438\u0448\u0443.\u00a0<\/p>\n<h2>\u041f\u043e\u0441\u043b\u0435\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<blockquote>\n<p>The <strong>devil<\/strong> is in the <strong>details<\/strong>.<\/p>\n<\/blockquote>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u044f \u0441 \u043e\u0434\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0431\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0432\u0441\u0435\u0445 \u0441\u0442\u0430\u0434\u0438\u044f\u0445 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f. \u0422\u0435\u0437\u0438\u0441\u044b \u0442\u0438\u043f\u0430 \u201c\u041b\u0435\u0433\u0447\u0435 \u043b\u0438 \u0440\u0443\u0431\u0438\u0441\u0442\u0430\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c, \u0447\u0435\u043c \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u201d \u0438 \u201c\u041b\u0443\u0447\u0448\u0435 \u043b\u0438 \u044d\u043b\u0438\u043a\u0441\u0438\u0440, \u0447\u0435\u043c \u0440\u0443\u0431\u0438\u201d \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u043c\u044b\u0441\u043b\u0430. \u041c\u0435\u043d\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043f\u0435\u0440\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043c\u043d\u043e\u0433\u043e\u0435 \u0440\u0430\u0437\u0434\u0440\u0430\u0436\u0430\u043b\u043e. \u041f\u0440\u043e\u0448\u043b\u043e \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u044f, \u0438 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u043c\u0438, \u0441\u0442\u0430\u043b\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c\u0438 \u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u043c\u0438. \u0410 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0448\u0442\u0443\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0438 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439.\u00a0<\/p>\n<p>\u0420\u0443\u0431\u0438 \u0432\u0441\u0435 \u0435\u0449\u0451 \u0445\u043e\u0440\u043e\u0448 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0438\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c \u043d\u0430 \u0432\u0441\u0435 \u0432\u0430\u0448\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0439\u0434\u0443\u0442\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043b\u0438\u0431\u044b. \u0418 \u0434\u0430\u0436\u0435 \u043d\u0430 \u0432\u0441\u0435 \u043a\u043e\u0441\u044f\u043a\u0438 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u043b\u0430\u0442\u043a\u0438 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b. \u041a \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0432\u044b\u043a\u0430\u0435\u0448\u044c.<\/p>\n<p>\u042d\u043b\u0438\u043a\u0441\u0438\u0440 \u0445\u043e\u0440\u043e\u0448 \u0438 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0443\u0436\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u0412 \u043a\u043e\u0434\u0435 \u0432\u0435\u0449\u0438 \u0434\u0435\u043b\u0430\u044e\u0442\u0441\u044f \u044f\u0432\u043d\u043e, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c. \u0415\u0441\u0442\u044c \u0432\u0441\u044f\u043a\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0435 \u0448\u0442\u0443\u043a\u0438 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043d\u0435 \u0442\u0430\u0449\u0438\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0434\u0438 background jobs, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u0430\u044f. \u0418 \u043a \u044d\u0442\u043e\u043c\u0443 \u0442\u043e\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u043a\u0430\u0435\u0448\u044c.<\/p>\n<p>\u041c\u043d\u0435 \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0434\u043e\u043d\u0435\u0441\u0442\u0438 \u0434\u0432\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u044b\u0441\u043b\u0438.<\/p>\n<p><strong>\u041f\u0440\u0438 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0447\u0438\u0441\u0442\u044b\u043c \u0432\u0437\u0433\u043b\u044f\u0434\u043e\u043c.<\/strong>\u00a0<\/p>\n<p>\u041e\u0442\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0437\u043d\u0430\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u043e\u0432, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0441\u0445\u043e\u0434\u0441\u0442\u0432\u0430. \u042d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e. \u041d\u043e, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c, \u043f\u0441\u0438\u0445\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438. \u041c\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043b\u0430\u043d \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0431\u044b \u0432 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"erlang\">Ruby |> forget_OOP |> undestand_functional_programming |> use_TDD |> be_ready_and_patient |> RTFM |> practice |> practice  Oh! Elixir<\/code><\/pre>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0438\u0432 \u043e\u043f\u044b\u0442 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u043e, \u043a\u0430\u043a \u043f\u0438\u0448\u0435\u0448\u044c \u043a\u043e\u0434 \u043d\u0430 \u0441\u0432\u043e\u0451\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c.<\/strong><\/p>\n<p>\u041f\u043e\u043a\u0430\u0436\u0443 \u0443\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 Codewars. \u0412\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u0434\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u0440\u0443\u0431\u0438.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043f\u043e \u043a\u0440\u0430\u0441\u043e\u0442\u0435 \u0438\u0437 \u0440\u0435\u0439\u0442\u0438\u043d\u0433\u0430<\/p>\n<pre><code class=\"ruby\">def human_years_cat_years_dog_years(human_years)   cat_year = 15   dog_year = 15      if human_years == 1     human_cat_dog = [human_years, cat_year, dog_year]   end   if human_years == 2     cat_year += 9     dog_year += 9     human_cat_dog = [human_years, cat_year, dog_year]   end   if human_years > 2     cat_year += 9 + 4 * (human_years - 2)     dog_year += 9 + 5 * (human_years - 2)     human_cat_dog = [human_years, cat_year, dog_year]   end   human_cat_dog  end<\/code><\/pre>\n<p>\u041c\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<pre><code class=\"ruby\">def human_years_cat_years_dog_years(human_years)   [human_years, cat_years(human_years), dog_years(human_years)] end     def dog_years(years)   case years    when 1      15   when 2      24   else     24 + (years - 2) * 5   end end    def cat_years(years)   case years    when 1     15   when 2     24   else     24 + (years - 2) * 4   end end<\/code><\/pre>\n<p>\u00a0\u0425\u043c, \u0430 \u0442\u0430\u043a \u043b\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445?<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e \u043a\u0440\u0430\u0441\u043e\u0442\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438\u0437 \u0440\u0435\u0439\u0442\u0438\u043d\u0433\u0430<\/p>\n<pre><code class=\"ruby\">def human_years_cat_years_dog_years(human_years)   cat_years=(human_years>=2)? 24+(human_years-2)*4:15   dog_years=(human_years>=2)? 24+(human_years-2)*5:15   return [human_years,cat_years,dog_years] end  <\/code><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u0440\u0443\u0431\u0438 \u0432 \u201c\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435\u201d. \u041d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0443\u043c\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u044b \u0434\u0435\u043b\u0430\u0435\u0442\u0435 \u0442\u043e, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0435 \u2014 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441 \u0432\u0430\u043c\u0438.\u00a0<\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/karuna\/blog\/650835\/\"> https:\/\/habr.com\/ru\/company\/karuna\/blog\/650835\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e<\/h2>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041d\u0430\u0442\u0430\u043b\u044c\u044f. \u0412 \u041a\u0430\u0440\u0443\u043d\u0435 \u044f \u043f\u0438\u0448\u0443 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043d\u0430 Elixir. <\/p>\n<p>\u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u043d\u0430 Elixir. \u0414\u043e \u044d\u0442\u043e\u0433\u043e \u044f \u043f\u0438\u0441\u0430\u043b\u0430 \u043d\u0430 Ruby. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0432\u0435\u0436\u0435\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0425\u0430\u0431\u0440 \u041a\u0430\u0440\u044c\u0435\u0440\u044b \u043f\u043e \u0437\u0430\u0440\u043f\u043b\u0430\u0442\u0430\u043c, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u2014 \u0437\u0430\u0440\u043f\u043b\u0430\u0442\u044b \u0440\u0443\u0431\u0438\u0441\u0442\u043e\u0432 \u0440\u0430\u0441\u0442\u0443\u0442, \u0430 Elixir \u0442\u0430\u043c \u043d\u0435\u0442. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043b\u044e\u0434\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u0438\u0441\u044c \u0441 Elixir \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043d\u0430 Ruby. \u042f \u0441\u0447\u0438\u0442\u0430\u044e, \u0447\u0442\u043e \u043d\u0430 \u044d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u0432\u0445\u043e\u0434 \u0432 \u044f\u0437\u044b\u043a. Elixir \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0439, \u043d\u043e \u0432 \u043f\u0435\u0440\u0432\u044b\u0435 \u043c\u0435\u0441\u044f\u0446\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0430 \u0441 \u043d\u0438\u043c \u043c\u043d\u0435 \u0441\u0430\u043c\u043e\u0439 \u0442\u0430\u043a \u043d\u0435 \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c. \u041d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0439, \u0447\u0442\u043e \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u043d\u0430\u0437\u0430\u0434. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0438 <s>\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430<\/s> \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430.<\/p>\n<blockquote>\n<p><strong>Elixir<\/strong> is a functional programming language which looks <em><u>similar<\/u><\/em> to <strong>Ruby<\/strong>.<\/p>\n<\/blockquote>\n<p>\u0412 IT \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0440\u0443\u0431\u0438\u0441\u0442\u044b \u043b\u0435\u0433\u043a\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 Elixir. \u0415\u0449\u0451 \u0431\u044b \u2014 \u0441\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u044c \u044f\u0437\u044b\u043a\u0430 Jose Walim \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0440\u0443\u0431\u0438\u0441\u0442. \u041d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0443\u0431\u0438\u0441\u0442, \u0430 core \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a Ruby on Rails. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e Elixir \u2014 \u044d\u0442\u043e Ruby \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u043a\u0430\u0447\u043a\u0438. \u0422\u0435\u0431\u0435 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a \u0436\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\/\u0431\u044b\u0441\u0442\u0440\u043e\/\u043a\u043b\u0430\u0441\u0441\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u043d\u0451\u043c, \u043f\u043b\u044e\u0441\u043e\u043c \u0438\u0434\u0451\u0442 \u0432\u0441\u044f \u043c\u043e\u0449\u044c Erlang\u2019\u0430. \u041c\u043d\u0435 \u0432 \u0441\u0432\u043e\u0451 \u0432\u0440\u0435\u043c\u044f \u043e\u0447\u0435\u043d\u044c \u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f Ruby. \u0418 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 Elixir \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043c\u0430\u043d\u0447\u0438\u0432\u043e\u0439 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u043e\u0439.<\/p>\n<h2>Ruby |> Elixir\u00a0<\/h2>\n<p>\u0418\u0437\u0443\u0447\u0430\u044f \u043d\u043e\u0432\u0443\u044e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e, \u044f \u0441\u0442\u0440\u0435\u043c\u043b\u044e\u0441\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438. \u0414\u0430, \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442 \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439. \u041e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c. \u0418 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0448\u0442\u0443\u043a\u0438.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0431\u0435\u0433\u043b\u043e\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0430 \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u0432 \u043c\u043e\u0435\u0439 \u0433\u043e\u043b\u043e\u0432\u0435 \u0431\u044b\u043b \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043b\u0430\u043d \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u044f\u0437\u044b\u043a\u0430\u043c\u0438. \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u201c|>\u201d \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435.<\/p>\n<pre><code class=\"erlang\">Ruby |> remove_OOP() |> add_some_functions() |> save_TDD() |> add_OTP() |> save_syntactic_sugar() {:ok, Elixir}<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0448\u0430\u0433\u0438. \u0417\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e \u041e\u041e\u041f. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0411\u0443\u0434\u0435\u0442 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435. \u041d\u043e \u0442\u0435\u0441\u0442\u044b \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u044f\u043b. \u0415\u0441\u0442\u044c \u0446\u0435\u043b\u0430\u044f \u043d\u043e\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c Open Telecom Platform. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c VS Code.<\/p>\n<pre><code class=\"ruby\">%{a: 1} # map in Elixir {a: 1} # hash in Ruby  # Lists [1, 2, true, 3] # Elixir, Ruby # Concatenate lists [1, 2, true, 3] ++ [5, 7] # Elixir [1, 2, true, 3] + [5, 7]  # Ruby  # Calling function\/method String.reverce(\"hello\") # Elixir \"hello\".reverse         # Ruby  # An anonymous function fn(x) -> x * x end # ELixir -> x {x * x} # lambda in Ruby  # Using each Enum.each([1, 2], &amp;(IO.puts &amp;1)) # Elixir [1, 2].each { |i| puts i }       # Ruby  # Defining a function in Elixir def hello do   \"result\" end # Defining a method in Ruby def hello   \"result\" end  # Defining a module in Elixir defmodule Example do end # Defining a module in Ruby module Example end<\/code><\/pre>\n<p>\u041e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0435. \u041f\u043e\u0434\u0443\u043c\u0430\u0435\u0448\u044c: \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0438\u043c\u044f \u043c\u043e\u0434\u0443\u043b\u044f.\u00a0<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0433\u043e\u0434 \u0432\u0438\u0441\u043e\u043a\u043e\u0441\u043d\u044b\u043c.\u00a0<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">class Year  def self.leap?(year)    @year = year    div_by?(4) &amp;&amp; ( !div_by?(100) || div_by?(400) )  end    def self.div_by?(number)    @year % number == 0  end end<\/code><\/pre>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">defmodule Year do  def leap?(year) do    div_by?(year, 4) &amp;&amp; ( !div_by?(year, 100) || div_by?(year, 400) )  end   def div_by?(year, number) do    rem(year, number) == 0  end end<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0433\u043e\u0434. \u041e\u0441\u0442\u0430\u0442\u043e\u043a \u043e\u0442 \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u041d\u0430\u0434\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c do \u043f\u0440\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.\u00a0\u00a0<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0438 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Elixir. \u041e\u043d \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c. \u0414\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0442\u044b \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u043e\u0432 \u044f \u0431\u0435\u0440\u0443 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 Ruby minitest., \u0442.\u043a. \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b Elixir \u0443 \u043d\u0430\u0441 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 Test Driven Development. \u0411\u044b\u0432\u0448\u0438\u0435 \u0440\u0443\u0431\u0438\u0441\u0442\u044b, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430\u043a\u043b\u0435\u043f\u0430\u043b\u0438 \u0443\u0436\u0435 \u0441\u0435\u0431\u0435 <a href=\"https:\/\/github.com\/antonmi\/espec\">espec<\/a>. \u041e\u043d, \u043f\u0440\u0430\u0432\u0434\u0430, \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u043f\u0440\u0438\u0436\u0438\u043b\u0441\u044f. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u2014 \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e minitest \u0432\u044b \u0445\u043e\u0442\u044c \u0440\u0430\u0437 \u0432\u0438\u0434\u0435\u043b\u0438. \u0418 \u043f\u043e\u043c\u043d\u0438\u043c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">require 'minitest\/autorun' require_relative 'leap'  class YearTest &lt; Minitest::Test  def test_year_not_divisible_by_4_common_year    # skip    refute Year.leap?(2015), \"Expected 'false', 2015 is not a leap year.\"  end   def test_year_divisible_by_4_not_divisible_by_100    assert Year.leap?(1996), \"Expected 'true', 1996 is a leap year.\"  end   def test_year_divisible_by_100_not_divisible_by_400    refute Year.leap?(2100), \"Expected 'false', 2100 is not a leap year.\"  end   def test_year_divisible_by_400    assert Year.leap?(2000), \"Expected 'true', 2000 is a leap year.\"  end   def test_year_divisible_by_200_not_divisible_by_400    # skip    refute Year.leap?(1800), \"Expected 'false', 1800 is not a leap year.\"  end end<\/code><\/pre>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">Code.load_file(\"leap.exs\", __DIR__)  ExUnit.start() ExUnit.configure(exclude: :pending, trace: true)  defmodule LeapTest do  use ExUnit.Case   test \"2015 year not divisible by 4\" do    refute Year.leap?(2015)  end   # @tag :pending  test \"1996 year divisible by 4 not divisible by 100 leap year\" do    assert Year.leap?(1996)  end   test \"2100 year divisible by 100 not divisible by 400\" do    refute Year.leap?(2100)  end   test \"2000 year divisible by 400 leap year\" do    assert Year.leap?(2000)  end   test \"1800 year divisible by 200 not divisible by 400\" do    refute Year.leap?(1800)  end end<\/code><\/pre>\n<p>\u0421\u043d\u043e\u0432\u0430 \u043e\u0442\u043b\u0438\u0447\u0438\u044f, \u043a\u0440\u043e\u043c\u0435 \u0443\u0436\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445, \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0432\u0435\u043b\u0438\u043a\u0438. \u0421\u043a\u0438\u043f\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0442\u044d\u0433. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043a\u0430\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439: \u201cexclude: :pending\u201d. <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u044b\u0441\u043b\u044c\u2026<\/p>\n<figure class=\"full-width\"><figcaption>Hey, Brain! I can write on Elixir?! <\/figcaption><\/figure>\n<h2>Ruby on Rails |> Phoenix<\/h2>\n<p>\u0421 \u044f\u0437\u044b\u043a\u043e\u043c \u0431\u044b\u043b\u043e \u043b\u0435\u0433\u043a\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0442\u0430\u043c \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438. \u0412 \u043a\u0440\u0430\u0442\u043a\u043e\u043c \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u044f \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u044d\u0442\u043e \u0441\u043e\u0431\u0440\u0430\u043b\u0430 \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435:<\/p>\n<pre><code>Rails controller == Phoenix controller (in Context) Rails model =~ Ecto (Schema + Repo + Query + ...) Rails view (template) =~ Phoenix view + template Rails serializer == Phoenix view Rails seeds\/tasks =~ Phoenix seeds\/tasks Rails migrations =~ Ecto migrations Rails console != Phoenix console<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430\u0436\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f.<\/p>\n<h3>\u041c\u0438\u0433\u0440\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f\u043c\u0438.<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">rails db:migrate rails db:rollback rails db:rollback STEP=2  rails db:migrate VERSION=20181213084911  rails db:migrate:redo VERSION=20181213084911 rails db:migrate:up VERSION=20181213084911 rails db:migrate:down VERSION=20181213084911<\/code><\/pre>\n<p>Elixir<\/p>\n<pre><code class=\"erlang\">mix ecto.migrate mix ecto.migrate -r Custom.Repo mix ecto.migrate -n 3  mix ecto.rollback mix ecto.rollback --step 2  mix ecto.migrate -to 20181213084911 mix ecto.rollback -to 20181213084911  # What?!<\/code><\/pre>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0433\u043e\u0432. \u041d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 Repo. \u041d\u0435\u043b\u044c\u0437\u044f \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c \u0438\u043b\u0438 \u043d\u0430\u043a\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 \u0442\u0430\u0441\u043a\u0438. \u0422\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0447\u043a\u0443 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439, \u0434\u0440\u0443\u0433 \u0437\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u2014 \u0434\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043a\u043e\u043f\u0430\u0442\u044c\u0441\u044f \u0432 API Ecto, \u0442\u043e \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043c\u043e\u0436\u043d\u043e&#8230;<\/p>\n<pre><code class=\"erlang\">Ecto.Migrator.with_repo(your_repo, &amp;Ecto.Migrator.run(&amp;1, :down, to: version))<\/code><\/pre>\n<p>\u0427\u0442\u043e \u044d\u0442\u043e \u0437\u0430 Repo, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439<\/h3>\n<p>\u042d\u0442\u043e \u0432\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0449\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0438\u0432\u0430\u0435\u0442 \u0438\u0437 \u043a\u043e\u043b\u0435\u0438. \u041f\u0435\u0440\u0432\u0430\u044f \u2014 \u0441\u0430\u043c\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0430. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u0430\u043a \u043c\u0438\u0440 \u0432\u0435\u0431 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u043f\u0438\u0442\u0430\u043d \u041e\u041e\u041f, \u0442\u0430\u043a \u0438 \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0432 \u043c\u0438\u0440\u0435 \u041e\u041e\u041f \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 ORM. \u0412 Rails \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0441 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u0438\u0437 \u0411\u0414 \u043a\u0430\u043a \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Active Record. \u0417\u0430\u0431\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435. \u041f\u0440\u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c Elixir \u043c\u044b \u0443\u0436\u0435 \u0443\u0442\u0440\u0430\u0442\u0438\u043b\u0438 \u0447\u0430\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0437\u0433\u043b\u044f\u0434\u0430 \u043d\u0430 \u043c\u0438\u0440. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432\u0440\u0435\u043c\u044f \u0443\u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u043e \u043a\u043e\u043d\u0446\u0430 (\u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438). \u041d\u0430 \u0441\u0446\u0435\u043d\u0443 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 Ecto. \u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435: Ecto \u2014 \u044d\u0442\u043e data mapper + query builder DSL.<\/p>\n<pre><code>Active Record is ORM, gives us:   - models and their data - associations between models - models validation  - database operations in an object-oriented style Ecto differs from other ORMs:   - schemas and their data - associations between schemas - changeset with validations  - database operations in functional style with Ecto modules (Repo, Query, etc.)<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c \u0432 \u0441\u0445\u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0410\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438 \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0434\u0435\u043b\u0438\u0441\u044c. \u0427\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0438\u0437 \u043a\u0430\u043a\u0438\u0445 \u043f\u043e\u043b\u0435\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0430\u0434\u043e \u043a\u0443\u0434\u0430-\u0442\u043e \u0445\u043e\u0434\u0438\u0442\u044c. \u0421\u0445\u0435\u043c\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0415\u0441\u0442\u044c \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0439 \u043d\u044e\u0430\u043d\u0441: \u0441\u0445\u0435\u043c\u0430 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u043b\u044f. \u0421\u0445\u0435\u043c\u043e\u0439 \u043c\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0417\u0430\u0447\u0435\u043c? \u042f \u043c\u043e\u0433\u0443 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:\u00a0<\/p>\n<p>1. \u041a\u0430\u043a\u043e\u0435-\u0442\u043e \u043f\u043e\u043b\u0435 \u0441\u0442\u0430\u043b\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043c\u0435\u043d\u044f\u0442\u044c, \u043d\u043e \u043e\u043d\u043e \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438\/\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0441\u0445\u0435\u043c\u044b, \u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0411\u0414.\u00a0<\/p>\n<p>2. \u0420\u0430\u0437\u043d\u044b\u0435 \u043d\u0430\u0431\u043e\u0440\u044b \u043f\u043e\u043b\u0435\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u0432. \u0420\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043e\u0431\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430\u0436\u0443\u0442\u0441\u044f \u0441\u0438\u043d\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u2014 \u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0430 \u0434\u043b\u044f \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0439\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445.\u00a0<\/p>\n<p>Ruby<\/p>\n<pre><code class=\"ruby\">class OnlineTracking &lt; ActiveRecord::Base  belongs_to :startup  belongs_to :expert, class_name: 'User'  has_one :expert_startup_rate, class_name: 'ExpertAnketa::StartupRate', dependent: :destroy  has_many :slots, class_name: 'OnlineTracking::Slot', foreign_key: :online_tracking_id   validates :startup_id, presence: true  validates :start_at, presence: true  validates :weeks, presence: true, numericality: { only_integer: true }   enum pause_status: {    disabled: 0, # \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435    date_changed: 1, # \u043f\u0435\u0440\u0435\u043d\u043e\u0441  }   after_create :make_anketas  after_update :update_startup_leads, if: Proc.new { |ot| ot.finished_at.present? || ot.deleted? }<\/code><\/pre>\n<p>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0445\u0435\u043c\u044b, \u043d\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043d\u0438\u0445 changeset (Ecto.Changeset). \u0427\u0442\u043e \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442? Changeset \u2014\u00a0\u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u0435\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043e\u0442 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043e\u0442 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430\u2026 \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u044f \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u041d\u0415 \u0447\u0435\u0440\u0435\u0437 changeset. \u0425\u043e\u0442\u044f \u0441\u0442\u043e\u0438\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0443: \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f Repo.update_all\/3, \u043b\u0438\u0431\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0447\u0438\u0441\u0442\u044b\u0439 SQL-\u0437\u0430\u043f\u0440\u043e\u0441. \u041d\u043e \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0439\u0442\u0438 \u0432 \u043e\u0431\u0445\u043e\u0434.\u00a0<\/p>\n<p>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c \u2014 \u043d\u043e \u0440\u043e\u0432\u043d\u043e \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0443\u0437\u043d\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u0443 \u0441\u0445\u0435\u043c\u044b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e changeset\u2019\u043e\u0432. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0447\u0435\u043c\u0443 \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-329410","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/329410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=329410"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/329410\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=329410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=329410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=329410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}