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

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