如何重构此代码块使其干燥

时间:2019-08-27 22:00:07

标签: ruby class methods controller dry

如何使该代码块变干? 我知道干燥意味着不要重复自己,但我看不到任何明显的重构机会。

索引,显示,编辑和创建似乎是基本/必需的方法。他们对我来说似乎很干。

我不确定后的方法。

到目前为止,除了谷歌搜索之外,我没有尝试过其他任何方法。

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

此代码段没有附加rails后端。我假设它只是理论上的-希望我们重构代码以使其更短。

2 个答案:

答案 0 :(得分:1)

恕我直言,你可以做类似的事情。

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

我建议您创建一个关注点来管理异常并逐个呈现每个特定的错误。这样一来,您就可以避免在每种操作中都采用两种方式来呈现好与坏的情况。

答案 1 :(得分:0)

我不得不猜测一下您的ApplicationControllerUser类中的内容。但是明显重复的代码是@user = User.find(params[:id])。您的showedit方法都只运行这一行。因此,他们做的事情完全相同,而这是不应该做的。一种方法一件事。

此外,一旦将showedit解析为一个方法,您的createupdatedestroy方法应调用它,而不是重复线。

接下来,我不会使用new作为方法名称,因为BasicObject::new已经使用了它。我测试了几件事,但还不清楚:

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" 

查看何时调用自己的new方法和何时调用BasicObject::new会花费更多的精力。因此,如果您甚至完全需要它,我会将其更改为new_user -我不明白为什么同时需要它和您的create方法。 (如果不需要,请摆脱它。)

最后,@user = User.find(params[:id])并不意味着要显示或编辑,因此,应该了解要尝试执行的操作并提供一个反映该名称的名称(例如set_user_id)也要完成。