Reputation: 62
How do I go about making this code block dry? I understand that dry means dont repeat yourself but I don't see any obvious opportunity for refactoring.
Index, show, edit, and create seem like basic/necessary methods. They appear to be pretty dry to me.
The methods after I am not sure about.
I haven't tried anything other than googling so far.
class UsersController < ApplicationController
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def edit
@user = User.find(params[:id])
end
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: @user }
else
format.html { render :new }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
Slack.notify_channel
end
def update
@user = User.find(params[:id])
respond_to do |format|
if @user.update(user_params)
format.html { redirect_to @user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: @user }
else
format.html { render :edit }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
Slack.notify_channel
end
def destroy
@user = User.find(params[:id])
@user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
Slack.notify_channel
end
private
def user_params
params.require(:user).permit(:username, :email)
end
end
There is no rails backend attached to this code snippet. I am assuming it is just theoretical - wanting us to refactor the code to make it shorter.
Upvotes: 0
Views: 181
Reputation: 36
IMHO you can do something like that.
class UsersController < ApplicationController
include ExceptionHandling
before_action :load_user, only: [:show, :edit, :update, :destroy]
after_action :slack_notify_channel, only: [:create, :update, :destroy]
def index
@users = User.all
end
def new
@user = User.new
end
def create
@user = User.create!(user_params)
respond_to do |format|
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: @user }
end
end
def update
@user.update!(user_params)
respond_to do |format|
format.html { redirect_to @user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: @user }
end
end
def destroy
@user.destroy!
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def load_user
@user = User.find(params[:id])
end
def slack_notify_channel
Slack.notify_channel
end
def user_params
params.require(:user).permit(:username, :email)
end
end
I would recommend you to create a concern to manage exceptions and render each specific error by exception. Then you can avoid having two ways in each action to render a good and bad case.
Upvotes: 1
Reputation: 6165
I have to guess a bit about what's in your ApplicationController
and User
classes. But the obviously repeated code is @user = User.find(params[:id])
. Your show
and edit
methods both just run this line. So, they do exactly the same thing, which they oughtn't to do. One method for one thing.
Also, once you resolve show
and edit
into a single method, your create
, update
and destroy
methods should call it instead of repeating the line.
Next, I wouldn't use new
as a method name, since it is already used by BasicObject::new
. I tested a few things and it gets pretty unclear:
class Test
attr_reader :test
def initialize
@test = 'test'
end
end
class Test2
attr_reader :test2
def new
p 'test2new'
@test2 = Test.new
end
end
testx = Test2.new
p testx.new.test
p testx.test2.test
=> "test2new"
=> "test"
=> "test"
It takes extra effort to see when you're calling your own new
method and when you're calling BasicObject::new
. So, I'd change that to new_user
or something, if you even need it at all — I don't see why you need both it and your create
method. (If you don't need it, get rid of it.)
Finally, @user = User.find(params[:id])
doesn't imply either showing or editing, so understanding what you're trying to do and coming up with a name that reflects it (e.g. set_user_id
) is something that ought to be done as well.
Upvotes: 0