Ruby on Rails Abstraction Helpers
Tags: 100wordsaday, inkedin, ruby, rails
Published: 2022-03-02 03:08:37

- While Building Ruby on Rails Application there might a situation where you need to evaluate or use a block of code or methods in multiples places of the application, for examples we need to find the :id of the user that is currently login before updating data to the database or for that user to be able to access a different page and data. 

## Class Scoped Private Helper methods

- Privates helpers methods are Define after the `private_` reserved keyword in ruby and are only available to the scope or the class that it's define within. 

**Here an example from a SessionController that it purpose it to make sure the user trying to log into the application is a valid user and redirect the user to the appropriate view page.**

```ruby
class SessionsController < ApplicationController

	def home; end
	def new; end
	
	def create
		if params[:provider] == "github"
			user = User.find_or_create_from_github_omniauth(auth)
				if user.persisted?
					log_in(user)
					redirect_to user_path(user)
				else
					flash[:message] = "There was an error while trying to authenticate you..."
					redirect_to root_path
				end
			else
				@user = User.find_by(email: params[:email])
				if @user && @user.authenticate(params[:password])
				log_in(@user)
				redirect_to user_path(@user)
			else
				flash[:message] = "Invalid Login Information. Please try again."
				redirect_to login_path
			end	
		end
	end
	
	def destroy
		log_out if logged_in?
		flash[:message] = "You have successfully logged out."
		redirect_to root_path
	end
	
	private
	
	def auth
		request.env['omniauth.auth']
	end
end
```

- In the 3rd line of the create method of this Session class, we call the auth private helper method that is defined at the end of the class block.

- `user = User.find_or_create_from_github_omniauth(auth)`

**These methods are a block of code accessible only to this class scope, not to another class on another file.**

## Global Scoped Helpers 
- To my understanding, global helper method are the next level of abstraction where we have a single file for in `app/helpers`  directory 
these helpers have module that are similar to class but more compartmentalized, so in the application controller we need to include these helpers methods, so we can use them in the controller and views example below 👇.
```ruby
class ApplicationController < ActionController::Base
	# Prevent CSRF attacks by raising an exception.
	protect_from_forgery with: :exceptio
	# For APIs, you may want to use :null_session instead.
	# Give access to helper methods in the view
	include SessionsHelper, BookmarksHelper, TagsHelper
end
```

**Above we are using the include method to give access to all  any controller than inherit from the Application controller so the Helpers module methods are available to use within the controller's scope.**

**Example of The Session Helper module that we are including in the above controller.**

```ruby
	module SessionsHelper

	# Logs In The given user.
	def log_in(user)
		session[:user_id] = user.id
	end
	
	# Returns the current logged-in user (if any).
	def current_user
		@current_user ||= User.find_by(id: session[:user_id])
	end
	
	# Returns true if the user is logged in, false otherwise.
	def logged_in?
		!current_user.nil?
	end
	
	# Log Out the current user.
	def log_out
		session.delete(:user_id)
		@current_user = nil
	end
	
	# Redirect to Root if not logged in.
	def redirect_if_not_logged_in
		redirect_to root_path if !logged_in?
	end
end
```

- In the above block of code we have a few methods define that we are using to log in the user, logout, current_user & redirect_if_not_logged_in. These methods are a block of code or a piece of code that perform a single or multiples action that would be repeated many times in the controller. This is How We keep our applications DRY.
- At first this might have seen a little mundane or lot to take in, but once you use the helper module and test them out it would clean up an abstract your code massively. 
- A Little way that helped me understand this easily is looking at every method  and objects as a block or cube of code or  small blocks that call upon each other and perform a function or and outcome, Hope this was helpful to someone. 

- **NOTE: This is one of 30 blogs that I would be attempting to write over the next 30 days to improve my writing skills.**