The value of DRY code.
The concept of Do Not Repeat Yourself or DRY in coding is a concept most programmers learn from the beginning. Similar to a real life conversation, you wouldn’t like very much if whomever you were conversing with kept saying the same thing over and over again; likewise if you yourself had to keep bringing up the same point.
This concept translates very well to coding. The idea of stating something only once and have it carry through the entire ‘conversation’ between you and the application. As a programmer you don’t want to have to code the same thing twice. Below is a simple example of how to implement certain methods to enforce DRY coding.
Here is an example from a simple Rails blogging application, here is what the Articles Controller initially looked like:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
def new
@article = Article.new
end def edit
@article = Article.find(params[:id])
end
def create
@article = Article.new(params.require(:article).permit(:title, :description))
if @article.save
flash[:notice] = "Article was created successfully!" redirect_to @article
else
render 'new'
end
enddef update
@article = Article.find(params[:id])
if @article.update(params.require(:article).permit(:title, :description))
flash[:notice] = "Article was updated successfully!" redirect_to @article
else
render 'edit'
end
enddef destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to articles_path
end
end
There is a lot to unpack here, but this code is pretty clunky. With all the repetition, it increases the chance of an error. Notice how the line
@article = Article.find(params[:id])
occurs 4 times throughout the controller and yes I actually coded this 4 times over just to prove this point.
Notice that also in the create and update methods we have the line
(params.require(:article).permit(:title, :description))
we can fix this as well by introducing two methods to clean up this code.
Let’s take of the first problem, we’ll create some private methods for this controller, the first one will be called ‘set_article’.
def set_article
@article = Article.find(params[:id])
end
Now we need to make sure that ‘set_article’ gets used for those 4 methods.
At the top of the controller we add:
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit, :update, :destroy]
This means that before anything happens, those methods will implement the ‘set_article’ method, no longer having to code it over and over again!
Now for the ‘params.require …’ line that’s just ensuring that the articles have all the require attributes when they are being created, they must have a title and description. It can be cleaned up using another private method. This one will be called ‘article_params’
def article_params
params.require(:article).permit(:title, :description)
end
Now in the create and update methods, simply just pass in ‘article_params’ as the argument.
The shiny, new, DRY Articles Controller looks like this:
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit, :update, :destroy]def index
@articles = Article.all
enddef show
enddef new
@article = Article.new
enddef edit
enddef create
@article = Article.new(article_params)
if @article.save
flash[:notice] = "Article was created successfully!"
redirect_to @article
else
render 'new'
end
enddef update
if @article.update(article_params)
flash[:notice] = "Article was updated successfully!"
redirect_to @article
else
render 'edit'
end
enddef destroy
@article.destroy
redirect_to articles_path
endprivatedef set_article
@article = Article.find(params[:id])
enddef article_params
params.require(:article).permit(:title, :description)
end
end
Much better!