collectiveidea / interactor

Interactor provides a common interface for performing complex user interactions.
MIT License
3.36k stars 212 forks source link

Best Practices #89

Closed markalanevans closed 7 years ago

markalanevans commented 9 years ago

Goal

Assuming my "domian area" is "Bidding".

Options

module Bidding
  class AddBid
    include Interactor
    def call
      begin

        if(context.audience_bid_data.has_key?(:url))

          response = Intenta::Audience.create({
                                                  :url => context.audience_bid_data[:url]
                                              })

          if(response.status == 200)
            audience_id = response.body['data']['audience']['id'].to_i

            @audience_bid = AudienceBid.new(context.audience_bid_data)
            @audience_bid.advertiser_id = context.advertiser_id
            @audience_bid.audience_id = audience_id
            if @audience_bid.save
              context.audience_bid = @audience_bid
              # Cache
              Bidding::BuildAudienceBidCacheWorker.perform_async(context.audience_bid.id)
            else
              context.fail!( error: 'Failed to Create Bid')
            end
          else
            context.fail!(error: 'Failed to Create Audience')
          end
        else
          context.fail!(error: 'Missing param: url')
        end
      rescue Faraday::Error::TimeoutError => error
        context.fail!( error: error.message)
      end
    end
  end
end

Sample usage in a controller:

# POST /audience_bids
  # POST /audience_bids.json
  def create
    @audience_bid = AudienceBid.new(permitted_audience_bid_params)
    @audience_bid.advertiser_id = current_user.advertiser.id
    authorize @audience_bid

    context = {
        :advertiser_id => current_user.advertiser.id,
        :audience_bid_data => permitted_audience_bid_params
    }

    context = Bidding::AddBid.call(context)
    respond_to do |format|
      if context.success?
        format.html { redirect_to context.audience_bid, notice: 'AudienceBid was successfully created.' }
        format.json { render :show, status: :created }
      else
        format.html { render :new }
        format.json { render status: :unprocessable_entity, json: { success: false, info: @response[:error], errors: context.error } }
      end
    end

So many choices.... How would you organize it?

laserlemon commented 7 years ago

Closing as my upcoming focus will be on development of version 4.0. There are many potential ways to solve the issues you described and I don't think Interactor as a library is opinionated enough to provide an answer as to the "correct" solution.