1
\$\begingroup\$

I have a #change_account action in the accounts controller that verifies if the user has access to the requested account prior to changing the current_account which happens via setting the session[:account]. I am trying to find the best way/place to check that the user has access to the account.

class AccountsController < ApplicationController

#removed rest of controller that doesn't apply

  def change_account
    if check_if_user_has_access(params['user_account']['id'])
      session[:account] = (params[:user_account][:id])
      flash[:notice]= 'Successfully Changed Account!'
    else
      flash[:alert]= 'No access to this Account!'
    end
    redirect_to root_path
  end

  private

    def check_if_user_has_access(requested_account)
      current_user.user_accounts.any? {|h| h[:account_id] == requested_account.to_i}  
    end

end

I'm not sure if the logic should be kept in the controller or potentially placed in a service object. I have seen a few explanations that say that service objects are best used for complex actions which this doesn't seem to fit. The model doesn't seem like a good fit, whether in the user_accounts or accounts models.

Here is how I take the session variable and update the current_account:

class ApplicationController < ActionController::Base

  protect_from_forgery with: :exception

  private

  def current_account
    if current_user.user_accounts.where(active: true).count >= 1
      session[:account] = current_user.user_accounts.first.account_id if session[:account].nil?
      current_user.user_accounts.find_by_account_id(session[:account]).account
    else
      nil
    end
  end
  helper_method :current_account

end

Or I could call a service object such in my controller:

if VerifyAccessToAccount.call(params['user_account']['id'], current_user)

and then set up the service object:

class VerifyAccessToAccount
  def self.call(requested_account, user)
    user.user_accounts.any? {|h| h[:account_id] == requested_account.to_i}
  end
end
\$\endgroup\$
  • \$\begingroup\$ I think you are right on the money. The service object is a great option. Right now it's not a problem to put it in your controller, but if that functionality needs to be replicated in other places a service object is a must. There are other benefits like the service being easier to test and you are setting a precedence for other developers. \$\endgroup\$ – Ryan-Neal Mes Sep 26 '14 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.