Skip to content

Instantly share code, notes, and snippets.

@mattbeedle
Last active August 29, 2015 14:04
Show Gist options
  • Save mattbeedle/edf275a03628cf4992bf to your computer and use it in GitHub Desktop.
Save mattbeedle/edf275a03628cf4992bf to your computer and use it in GitHub Desktop.
strong_params vs object oriented rails
# strong_params version, with business logic tied to controller.
class Something
validates :name, :age, :miles_travelled, presence: true
validates :age, :miles_travelled, :coffee_consumed, :children_eaten,
numericality: { allow_blank: true }
end
class SomethingController < ApplicationController::Base
respond_to :html
def create
@something = Something.new something_params
@something.save
respond_with @something
end
private
def something_params
params.require(:something).
permit!(:name, :age, :miles_travelled, :coffee_consumed, :children_eaten)
end
end
# OO Version
# ActiveRecord treated as a repository. JUST for persisting and returning data
class Something < ActiveRecord::Base
end
# Controller is only responsible for calling out to our business logic,
# using "Tell don't ask"
class SomethingController < ApplicationController::Base
def create
something_creator.create(params[:something])
end
private
def something_creator
@something_creator ||= SomethingCreator.new(self, something_form)
end
def something_form
@something_form ||= SomethingForm.new(something)
end
def something
@something ||= Something.new
end
def something_create_succeeded(something)
respond_with something
end
def something_create_failed(something)
respond_with something
end
end
# A class with the Single Responsibility of creating somethings. Any "listener" can
# be passed in as long as it responds to "create_something_succeeded" and
# "create_something_failed"
class SomethingCreator
def initialize(listener, form)
@listener = listener
@form = form
end
delegate :model, to: :form
def create(params = {})
if form.validate(params)
form.save
listener.something_create_succeeded(model)
else
listener.something_create_failed(model)
end
end
private
attr_reader :listener, :form
end
# A class with the Single Responsiblity of validating/syncing data
# with the repository. Strong params is no longer required as only
# defined attributes are allowed through.
# Uses the reform gem: https://github.com/apotonick/reform/
class SomethingForm
include Reform
model :something
attribute :name, type: String
attribute :age, type: Integer
attribute :miles_travelled, type: Float
attribute :coffee_consumed, type: Integer
attribute :children_eaten, type: Integer, default: 0
validates :name, :age, :miles_travelled, presence: true
validates :age, :miles_travelled, :coffee_consumed, :children_eaten,
numericality: { allow_blank: true }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment