干掉这个Ruby代码

时间:2016-05-23 16:40:15

标签: ruby-on-rails ruby refactoring

最近,我开始使用Rubocop,一直在努力思考我的代码,如果我能写得更好。我有一个非常相似的创建和更新方法。 Rubocop抱怨该方法有太多代码[12/10]。我想知道你将如何遵循DRY原则。在我看来,respond_to应该被带到它自己的私有方法。但是我无法弄清楚从那以后最好的方法是什么:

  1. 闪光可以是:成功或:危险
  2. 一个检查模型是否已保存,另一个是否已更新。
  3. 不同的渲染取决于模型是否已保存或是否有错误
  4. 我也不知道我是不是应该一个人离开。事实上它是如此多余,实际上是在向我求助。终极我想拥有最干净的代码,我只是不确定我是否应该干这个方法

      def create
        @category = Category.new(category_params)
    
        respond_to do |format|
          if @category.save
            flash[:success] = 'Category Successfully Created'
            format.html { redirect_to admin_category_path(@category) }
            format.json { render :show, status: :created, location: @category }
          else
            flash[:danger] = 'Errors in creating category, see below'
            format.html { render :new }
            format.json { render json: @category.errors, status: :unprocessable_entity }
          end
        end
      end
    
      def update
        @category = Category.find(params[:id])
    
        respond_to do |format|
          if @category.update(category_params)
            flash[:success] = 'Category Successfully updated!'
            format.html { redirect_to admin_category_path(@category) }
            format.json { render :show, status: :created, location: @category }
          else
            flash[:danger] = 'Errors in updating category, missing information'
            format.html { redirect_to action: 'edit', id: @category.id }
            format.json { render json: @category.errors, status: :unprocessable_entity }
          end
        end
      end
    

3 个答案:

答案 0 :(得分:1)

尝试从createupdate制作单个方法没有任何意义,因为它们有两个非常不同的用途。

相反,您可以考虑以下事项:

  • 你真的需要json格式吗?如果您不使用它,您可以安全地删除这些行;
  • @category = Category.find(params[:id])移除update并将其移至before_action

    中的方法
    before_action :find_category, only: [:edit, :update]
    
    def find_category
      @category = Category.find(params[:id])
    end
    
  • 最后但同样重要的是,Rubocop并不总是有正确的答案:专注于清晰度!

答案 1 :(得分:0)

除了消息中的单个词之外,所有成功处理都是相同的;并且错误时的JSON处理是相同的。因此,可以将这些部分提取到create和update调用的方法中。代码不仅更简洁,对于读者来说,哪些行为是相同的,哪种行为不同也是显而易见的。我没有运行或测试过这段代码,但这里是:

def handle_success(created_or_updated)
  verb = created_or_updated == :created ? 'Created' : 'Updated'
  flash[:success] = "Category Successfully #{verb}"
  format.html { redirect_to admin_category_path(@category) }
  format.json { render :show, status: :created, location: @category }
end


def handle_failure_json
  format.json { render json: @category.errors, status: :unprocessable_entity }
end


def create
  @category = Category.new(category_params)

  respond_to do |format|
    if @category.save
      handle_success(:created)
    else
      flash[:danger] = 'Errors in creating category, see below'
      format.html { render :new }
      handle_failure_json
    end
  end
end


def update
  @category = Category.find(params[:id])

  respond_to do |format|
    if @category.update(category_params)
      handle_success(:updated)
    else
      flash[:danger] = 'Errors in updating category, missing information'
      format.html { redirect_to action: 'edit', id: @category.id }
      handle_failure_json
    end
  end
end

答案 2 :(得分:0)