Old and new shouts controllers I have a photo_shouts_controller.rb and text_shouts_controller.rb which both have almost similar implementations, and I would like to refactor it.

I have implemented a refactoring but I am not too sure if that is the best way to do it.

Current implementation

class PhotoShoutsController &lt; ApplicationController
  def create
    content = build_content
    shout = current_user.shouts.build(content: content)

    if shout.save
      redirect_to dashboard_path
    else
      redirect_to dashboard_path, notice: 'not created!'
    end
  end

  private

  def build_content
    PhotoShout.new(photo_shouts_parameters)
  end

  def photo_shouts_parameters
    params.require(:photo_shout).permit(:image)
  end
end

class TextShoutsController &lt; ApplicationController
  def create
    content = build_content
    shout = current_user.shouts.build(content: content)

    if shout.save
      redirect_to dashboard_path
    else
      redirect_to dashboard_path, notice: 'not created!'
    end
  end

  private

  def build_content
    TextShout.new(text_shouts_parameters)
  end

  def text_shouts_parameters
    params.require(:text_shout).permit(:body)
  end
end


My new implementation

ShoutBuild.rb

class ShoutBuild
  def initialize(current_user, shout_parameters, shout_class)
    @shout_parameters = shout_parameters
    @shout_class = shout_class
    @user = current_user
  end

  def build
    content = build_content
    @user.shouts.build(content: content)
  end

  private

  def build_content
    @shout_class.new(@shout_parameters)
  end
end


Controllers

class TextShoutsController &lt; ApplicationController
  def create
    shout = ShoutBuild.new(current_user, text_shouts_parameters, TextShout).build

    if shout.save
      redirect_to dashboard_path
    else
      redirect_to dashboard_path, notice: 'not created'
    end
  end

  private

  def text_shouts_parameters
    params.require(:text_shout).permit(:body)
  end
end

class PhotoShoutsController &lt; ApplicationController
  def create
    shout = ShoutBuild.new(current_user, photo_shouts_parameters, PhotoShout).build

    if shout.save
      redirect_to dashboard_path
    else
      redirect_to dashboard_path, notice: 'not created!'
    end
  end

  private

  def photo_shouts_parameters
    params.require(:photo_shout).permit(:image)
  end
end
By moving the build statement into a service you actually aren't saving yourself much, even after the refactor you still have a bunch of code that isn't DRY. Depending on how big your application is I would move pretty much all of the logic for your create actions into either ApplicationController, or, more likely a module. The module could look like this:

module ShoutController
  def create
    shout = current_user.shouts.build(content: build_content)
    redirect_params = shout.save ? {} : {notice: 'not created'}
    redirect_to dashboard_path, redirect_params
  end
end


Then your controllers would simply be:

class PhotoShoutsController &lt; ApplicationController
  include ShoutController

  private

  def build_content
    PhotoShout.new(params.require(:photo_shout).permit(:image))
  end
end


And

class TextShoutsController &lt; ApplicationController
  include ShoutController

  private

  def build_content
    TextShout.new(params.require(:text_shout).permit(:body))
  end
end