SlideShare a Scribd company logo
1 of 52
Download to read offline
THE END
OF RAILS?
@APOTONICK
THE ILLUSION
OF STABLE APIS
@APOTONICK
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
End of-rails-wids
“Most Rails developers do not write
object-oriented Ruby code.
They write MVC-oriented Ruby code by
putting models and controllers in the
expected locations.
It takes 2-3 years before developers
realize: “Rails is just Ruby.”
-- Mike Perham
End of-rails-wids
End of-rails-wids
End of-rails-wids
RAILS’
OBSESSION
WITH “MVC”
End of-rails-wids
class User < ActiveRecord::Base
validates :name, length: 20
validates :email, format: email
validates :age, numericality: true
class User < ActiveRecord::Base
validates :name, length: 20
validates :email, format: email
validates :age, numericality: true
User.create(
name: “RISE!”,
email: “rise@”
age: 21
)
class User < ActiveRecord::Base
validates :name, length: 20
validates :email, format: email
validates :age, numericality: true
class User < ActiveRecord::Base
validates :name, length: 20
validates :email, format: email
validates :age, numericality: true
class User < ActiveRecord::Base
validates :name, length: 20
validates :email, format: email
validates :age, numericality: true
User.create(
name: “RISE! This user is by ADMIN!”,
email: “rise@”
age: 21
)
class User < ActiveRecord::Base
validates :name, length: 20
validates :email, format: email
validates :age, numericality: true
User.create(
name: “RISE! This user is by ADMIN!”,
email: “rise@”
age: 21
)
class User < ActiveRecord::Base
validates :name, length: 20,
unless: → { creator_is_admin? }
validates :email, format: email
validates :age, numericality: true
User.create(
name: “RISE! This user is by ADMIN!”,
email: “rise@”
age: 21
)
End of-rails-wids
End of-rails-wids
class User
End of-rails-wids
defmodule User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name
field :email
field :age, :integer
end
def changeset(user, params  :empty) do
user
|> cast(params, ~w(name email), ~w(age))
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..100)
|> unique_constraint(:email)
end
end
End of-rails-wids
defmodule User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name
field :email
field :age, :integer
end
def changeset(user, params  :empty) do
user
|> cast(params, ~w(name email), ~w(age))
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..100)
|> unique_constraint(:email)
end
end
defmodule User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name
field :email
field :age, :integer
end
def changeset(user, params  :empty) do
user
|> cast(params, ~w(name email), ~w(age))
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..100)
|> unique_constraint(:email)
end
end
class User
User
User.Admin
End of-rails-wids
class User::Create < Trailblazer::Operation
model User
contract do
property :name
property :email
property :age, type: Integer
validates :email, format: email
validates :age, inclusion: 1..200
end
def process(params)
validate(params) do
contract.save
end
end
end
End of-rails-wids
class User::Create < Trailblazer::Operation
model User
contract do
property :name
property :email
property :age, type: Integer
validates :email, format: email
validates :age, inclusion: 1..200
end
def process(params)
validate(params) do
contract.save
end
end
end
class User::Create < Trailblazer::Operation
model User
contract do
property :name
property :email
property :age, type: Integer
validates :email, format: email
validates :age, inclusion: 1..200
end
def process(params)
validate(params) do
contract.save
end
end
end
class User
User::Create
User::Create::Admin
End of-rails-wids
APIs
MUST
CHANGE!
End of-rails-wids
End of-rails-wids
End of-rails-wids
APIs
MUST
CHANGE!
APIs
MUST
CHANGE!INNOVATION ==
@APOTONICK

More Related Content

Viewers also liked

Black Ops of TCP/IP 2011 (Black Hat USA 2011)
Black Ops of TCP/IP 2011 (Black Hat USA 2011)Black Ops of TCP/IP 2011 (Black Hat USA 2011)
Black Ops of TCP/IP 2011 (Black Hat USA 2011)Dan Kaminsky
 
Introduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScriptIntroduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScripttmont
 
Who's More Functional: Kotlin, Groovy, Scala, or Java?
Who's More Functional: Kotlin, Groovy, Scala, or Java?Who's More Functional: Kotlin, Groovy, Scala, or Java?
Who's More Functional: Kotlin, Groovy, Scala, or Java?Andrey Breslav
 
Category theory for beginners
Category theory for beginnersCategory theory for beginners
Category theory for beginnerskenbot
 
How StorageMart Succeeds in Global & Local Search
How StorageMart Succeeds in Global & Local SearchHow StorageMart Succeeds in Global & Local Search
How StorageMart Succeeds in Global & Local SearchTrustpilot
 
Airbnb tech talk: Levi Weintraub on webkit
Airbnb tech talk: Levi Weintraub on webkitAirbnb tech talk: Levi Weintraub on webkit
Airbnb tech talk: Levi Weintraub on webkitnaseemh
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional WorldDebasish Ghosh
 
PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...
PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...
PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...EduSkills OECD
 
Lancement de PISA 2015 en France
Lancement de PISA 2015 en FranceLancement de PISA 2015 en France
Lancement de PISA 2015 en FranceEduSkills OECD
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 
The power of creative collaboration
The power of creative collaborationThe power of creative collaboration
The power of creative collaborationTable19
 
3 Ingredients to Spice Up Your Content Marketing
3 Ingredients to Spice Up Your Content Marketing3 Ingredients to Spice Up Your Content Marketing
3 Ingredients to Spice Up Your Content MarketingSemrush
 
Beyond the Gig Economy: How New Technologies Are Reshaping the Future of Work
Beyond the Gig Economy: How New Technologies Are Reshaping the Future of WorkBeyond the Gig Economy: How New Technologies Are Reshaping the Future of Work
Beyond the Gig Economy: How New Technologies Are Reshaping the Future of WorkThumbtack, Inc.
 

Viewers also liked (13)

Black Ops of TCP/IP 2011 (Black Hat USA 2011)
Black Ops of TCP/IP 2011 (Black Hat USA 2011)Black Ops of TCP/IP 2011 (Black Hat USA 2011)
Black Ops of TCP/IP 2011 (Black Hat USA 2011)
 
Introduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScriptIntroduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScript
 
Who's More Functional: Kotlin, Groovy, Scala, or Java?
Who's More Functional: Kotlin, Groovy, Scala, or Java?Who's More Functional: Kotlin, Groovy, Scala, or Java?
Who's More Functional: Kotlin, Groovy, Scala, or Java?
 
Category theory for beginners
Category theory for beginnersCategory theory for beginners
Category theory for beginners
 
How StorageMart Succeeds in Global & Local Search
How StorageMart Succeeds in Global & Local SearchHow StorageMart Succeeds in Global & Local Search
How StorageMart Succeeds in Global & Local Search
 
Airbnb tech talk: Levi Weintraub on webkit
Airbnb tech talk: Levi Weintraub on webkitAirbnb tech talk: Levi Weintraub on webkit
Airbnb tech talk: Levi Weintraub on webkit
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
 
PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...
PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...
PISA 2015 - Volume I: Excellence and Equity in Education and Volume II: Poli...
 
Lancement de PISA 2015 en France
Lancement de PISA 2015 en FranceLancement de PISA 2015 en France
Lancement de PISA 2015 en France
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
The power of creative collaboration
The power of creative collaborationThe power of creative collaboration
The power of creative collaboration
 
3 Ingredients to Spice Up Your Content Marketing
3 Ingredients to Spice Up Your Content Marketing3 Ingredients to Spice Up Your Content Marketing
3 Ingredients to Spice Up Your Content Marketing
 
Beyond the Gig Economy: How New Technologies Are Reshaping the Future of Work
Beyond the Gig Economy: How New Technologies Are Reshaping the Future of WorkBeyond the Gig Economy: How New Technologies Are Reshaping the Future of Work
Beyond the Gig Economy: How New Technologies Are Reshaping the Future of Work
 

End of-rails-wids

  • 2. THE ILLUSION OF STABLE APIS @APOTONICK
  • 15. “Most Rails developers do not write object-oriented Ruby code. They write MVC-oriented Ruby code by putting models and controllers in the expected locations. It takes 2-3 years before developers realize: “Rails is just Ruby.” -- Mike Perham
  • 21. class User < ActiveRecord::Base validates :name, length: 20 validates :email, format: email validates :age, numericality: true
  • 22. class User < ActiveRecord::Base validates :name, length: 20 validates :email, format: email validates :age, numericality: true User.create( name: “RISE!”, email: “rise@” age: 21 )
  • 23. class User < ActiveRecord::Base validates :name, length: 20 validates :email, format: email validates :age, numericality: true
  • 24. class User < ActiveRecord::Base validates :name, length: 20 validates :email, format: email validates :age, numericality: true
  • 25. class User < ActiveRecord::Base validates :name, length: 20 validates :email, format: email validates :age, numericality: true User.create( name: “RISE! This user is by ADMIN!”, email: “rise@” age: 21 )
  • 26. class User < ActiveRecord::Base validates :name, length: 20 validates :email, format: email validates :age, numericality: true User.create( name: “RISE! This user is by ADMIN!”, email: “rise@” age: 21 )
  • 27. class User < ActiveRecord::Base validates :name, length: 20, unless: → { creator_is_admin? } validates :email, format: email validates :age, numericality: true User.create( name: “RISE! This user is by ADMIN!”, email: “rise@” age: 21 )
  • 32. defmodule User do use Ecto.Schema import Ecto.Changeset schema "users" do field :name field :email field :age, :integer end def changeset(user, params :empty) do user |> cast(params, ~w(name email), ~w(age)) |> validate_format(:email, ~r/@/) |> validate_inclusion(:age, 18..100) |> unique_constraint(:email) end end
  • 34. defmodule User do use Ecto.Schema import Ecto.Changeset schema "users" do field :name field :email field :age, :integer end def changeset(user, params :empty) do user |> cast(params, ~w(name email), ~w(age)) |> validate_format(:email, ~r/@/) |> validate_inclusion(:age, 18..100) |> unique_constraint(:email) end end
  • 35. defmodule User do use Ecto.Schema import Ecto.Changeset schema "users" do field :name field :email field :age, :integer end def changeset(user, params :empty) do user |> cast(params, ~w(name email), ~w(age)) |> validate_format(:email, ~r/@/) |> validate_inclusion(:age, 18..100) |> unique_constraint(:email) end end
  • 39. class User::Create < Trailblazer::Operation model User contract do property :name property :email property :age, type: Integer validates :email, format: email validates :age, inclusion: 1..200 end def process(params) validate(params) do contract.save end end end
  • 41. class User::Create < Trailblazer::Operation model User contract do property :name property :email property :age, type: Integer validates :email, format: email validates :age, inclusion: 1..200 end def process(params) validate(params) do contract.save end end end
  • 42. class User::Create < Trailblazer::Operation model User contract do property :name property :email property :age, type: Integer validates :email, format: email validates :age, inclusion: 1..200 end def process(params) validate(params) do contract.save end end end