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

Wrangling Service Objects with method_struct

Wrangling Service Objects with method_struct

Service Object is a pattern of extracting business logic into a separate "service". It has gotten considerable traction in the Ruby ecosystem and is worth exploring. In this talk, I present how Service Objects can be implemented using method_struct.

You can find method_struct here: https://github.com/basecrm/method_struct

To learn more about testing with method_struct, read the accompanying blog post:
http://bunsch.pl/2014/10/14/wrangling-service-objects-with-method_struct/

marcinbunsch

October 14, 2014
Tweet

More Decks by marcinbunsch

Other Decks in Programming

Transcript

  1. A 'service' describes system interactions. Usually, these will involve more

    than one business model in our application. Steve Lorek Service Objects: What They Are, and When to Use Them
  2. class PostsController < ApplicationController ! def create @post = Post.new(post_params)

    ! if @post.save twitter = TwitterClient.new(current_user) twitter.tweet "Blogged: #{@post.title}" ! search = SearchClient.new search.index @post ! redirect_to @post, notice: 'Post was successfully created.' else render :new end end ! end
  3. class PostCreator < MethodStruct.new(:current_user, :post_params) ! def call post =

    Post.new(post_params) ! if post.save publish_to_twitter(post) index_post(post) end ! post end ! private ! def publish_to_twitter(post) twitter = TwitterClient.new(current_user) twitter.tweet "Blogged: #{post.title}" end ! def index_post(post) search = SearchClient.new search.index post end ! end
  4. class PostCreator < MethodStruct.new(:current_user, :post_params, { :method_name => :create })

    ! def create post = Post.new(post_params) ! if post.save publish_to_twitter(post) index_post(post) end ! post end ! private ! def publish_to_twitter(post) twitter = TwitterClient.new(current_user) twitter.tweet "Blogged: #{post.title}" end ! def index_post(post) search = SearchClient.new search.index post end ! end
  5. class PostCreator < MethodStruct.new(:current_user, :post_params, { :method_name => :create })

    ! def create post = Post.new(post_params) ! if post.save publish_to_twitter(post) index_post(post) end ! post end ! private ! def publish_to_twitter(post) twitter = TwitterClient.new(current_user) twitter.tweet "Blogged: #{post.title}" end ! def index_post(post) search = SearchClient.new search.index post end ! end
  6. class PostsController < ApplicationController ! def create @post = PostCreator.create(current_user,

    post_params) ! if @post.errors.none? redirect_to @post, notice: 'Post was successfully created.' else render :new end end end
  7. class PostCreator < MethodStruct.new(:current_user, :post_params) ! def call post =

    Post.new(post_params) ! if post.save TwitterPublisher.tweet(current_user, post) PostIndexer.index(post) end ! post end ! end