0

Foreword: maybe I misunderstand the conception of the service objects and should to design an another implementation. Thank you in advance.


I create the service object for a sms confirmations. User must confirm his actions when:

  • He submits a phone number (updates own profile);
  • He confirms the transaction;
  • He does other important action;

Here is the communication scheme: enter image description here

Code:

profile_controller:

def update

  @profile.assign_attributes(profile_params)
  if @profile.valid?
    confirm = SmsConfirmationService.new({user: current_user,
                                          phone: profile_params["phone"],
                                          kind: :phone})
    confirm.confirm_phone
  else
    ...
  end

end

sms_confirmation_service:

class SmsConfirmationService

  attr_reader :status

  def initialize(params)
    @user = params[:user]
    @phone = params[:phone]
    @kind = params[:kind]
  end

  def create_pin
    pin = Pin.new(code: rand(0000..9999).to_s.rjust(4, "0"),
                  profile_id: @user.profile.id)
    pin.save

    send_sms(pin.code)
  end

  def send_sms(code)
    # call to SMS-provider API and check the status

    render_view
  end

  def render_view
    template = ActionView::Base.new(ActionController::Base.view_paths, {})

    if @kind == :phone
      template.render(file: 'confirmation/confirm_phone')
    end
  end

end

I stuck on the render_view method. I get a 'Missing template profile/update', but according to logs, the template is rendered:

....
Rendered confirmation/confirm_phone.html.haml (6.7ms)
  (0.1ms)  begin transaction
  SQL (0.2ms)  INSERT INTO "pins" ("code", "profile_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["code", 7811], ["profile_id", 7], ["created_at", "2016-08-26 15:45:02.751384"], ["updated_at", "2016-08-26 15:45:02.751384"]]
  (1.0ms)  commit transaction
  (0.1ms)  begin transaction
  (0.1ms)  commit transaction
Completed 500 Internal Server Error in 1070ms (ActiveRecord: 3.3ms)

ActionView::MissingTemplate (Missing template profile/update, application/update with {:locale=>[:ru], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :haml, :jbuilder]}.

How to resolve it?

user1201917
  • 1,360
  • 1
  • 14
  • 27
  • Services are services--they don't have views. View-related stuff *calls* service objects. – Dave Newton Aug 26 '16 at 16:08
  • Is there a different concept for such cases? Can you point me in the right direction? – user1201917 Aug 26 '16 at 16:31
  • Such cases as what? Service objects, the way I understand them, are explicitly for moving functionality out of code not directly related to what's calling the objects. E.g., in a Rails controller, making calls to send SMS messages is a secondary concern to how the results of that SMS send is handled. Moving the SMS send itself into another class allows trivial testing of the controller itself (or whatever is using the SMS service object). – Dave Newton Aug 26 '16 at 18:18

0 Answers0