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

Dealing with Service Objects

Dealing with Service Objects

Conversation starter about working with service objects in Rails, given at Ruby/Rails Sofia meetup

Avatar for Radoslav Stankov

Radoslav Stankov

November 24, 2016
Tweet

More Decks by Radoslav Stankov

Other Decks in Technology

Transcript

  1. module UserDeactivator extend self def call(user, active: active) return if

    user.active == active user.update! active: active user.posts.update_all active: active user.votes.update_all active: active user.comments.update_all active: active user.following_association.update_all active: active user.followers_association.update_all active: active end end
  2. module SendPrivateMessage extend self def call(message, recipient, sender) return :invalid

    unless recipient.present? return :invalid unless recipient.receive_private_messages? message = Message.new message, sender, recipient return :not_saved unless message.save MessageMailer.user_message(message).deliver_later Metrics.track_create message, by: sender :success end end
  3. class RegistrationController < ApplicationController def create @user = User.new(user_params) @user.account

    = Account.new(account_params) @user.account.owner = @user if @user.valid? && @user.account.valid? @user.save! @user.account.save! AccountWasCreated.perform_later(account) redirect_to user_path(@user) else render :new end end end
  4. class RegistrationController < ApplicationController def create @registration = RegistrationForm.new(registration_params) if

    @registration.save redirect_to user_path(@registration.user) else render :new end end end
  5. class RegistrationForm include ActiveModel::Model attr_reader :user, :account attr_accessor :first_name, :last_name,

    :email, :name, :plan, :te # user validation validates :first_name, presence: true validates :last_name, presence: true validates :email, presence: true, email: true # account validation validates :account_name, presence: true # form custom validation validates :plan, inclusion: {in AccountPlan::VALUES} validates :terms_of_service, acceptance: true # ensure uniqueness
  6. validates :account_name, presence: true # form custom validation validates :plan,

    inclusion: {in AccountPlan::VALUES} validates :terms_of_service, acceptance: true # ensure uniqueness validate :ensure_unique_user_email validate :ensure_unique_account_name def initialize @user = User.new @account = Account.new owner: @user end def update(attributes) attributes.each do |name, value| public_send "#{name}=", value end if valid? & user.update(user_attributes) && account.update(acco account.users << user AccountWasCreated.perform_later(account) else
  7. def update(attributes) attributes.each do |name, value| public_send "#{name}=", value end

    if valid? & user.update(user_attributes) && account.update(acco account.users << user AccountWasCreated.perform_later(account) else false end end private def ensure_unique_user_email errors.add :email, 'already taken' if User.where(email: email). end def ensure_unique_account_name errors.add :name, 'already taken' if Account.where(name: name). end
  8. else false end end private def ensure_unique_user_email errors.add :email, 'already

    taken' if User.where(email: email). end def ensure_unique_account_name errors.add :name, 'already taken' if Account.where(name: name). end def user_attributes {first_name: first_name, last_name: last_name, email: email} end def account_attributes {plan: plan, name: name} end end
  9. class RegistrationForm include MiniForm::Model model :user, attributes: %i(first_name last_name email),

    save: t model :account, attributes: %i(name plan), save: true attributes :terms_of_service validates :plan, inclusion: {in AccountPlan::VALUES} validates :terms_of_service, acceptance: true def initialize @user = User.new @account = Account.new owner: @user end def perform account.users << user AccountWasCreated.perform_later(account) end end