Rails重构:某些控制器中的重复代码。它属于哪里?

时间:2013-08-28 20:46:34

标签: ruby-on-rails refactoring helper actioncontroller

我有几个控制器中出现的类似(重复?)代码。有时它在#update动作中,有时它在#update_multiple动作中......有时它在两者中。

在所有情况下,代码的主要用途是设置belongs_to关系,因此只能在控制器模型上设置product_id。它使用first_or_create,因此如果引用的Product不存在,则首先创建它。

重复代码:

product = Product.where(params[:product]).first_or_create if params[:product]
if product && params[:project][:code].present?
  project = Project.where(params[:project]).first_or_create 
  product.project = project if project
end
product.save if product

快速概述或关系: _Items & _Files belong_to 产品。产品可以belong_to 项目

我可以/应该将其提取到哪里?我不确定它是否应该进入产品(和项目)模型?或者也许在ApplicationController中?还是帮助者?

以下是'wild'中代码的一些示例:

#disk_files_controller.rb
  ...
  def update
    product = Product.where(params[:product]).first_or_create if params[:product]
    if product && params[:project][:code].present?
      project = Project.where(params[:project]).first_or_create
      product.project = project if project
    end
    product.save if product

    respond_to do |format|
      if @disk_file.update(disk_file_params)
        format.html { redirect_to @disk_file, notice: 'Disk_File was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @disk_file.errors, status: :unprocessable_entity }
      end
    end
  end

update_multiple

的示例
#inventory_items_controller.rb
  ...
  def update_multiple
    product = Product.where(params[:product]).first_or_create if params[:product]
    if product && params[:project][:code].present?
      project = Project.where(params[:project]).first_or_create 
      product.project = project if project
    end
    product.save if product

    @inventory_items = InventoryItem.find(params[:inventory_item_ids])
    update_hash = {product_id: product.id}
    update_hash.merge({project_code: params[:project][:code]}) unless params[:project][:code].blank?
    InventoryItem.update_all(update_hash, {id: params[:inventory_item_ids]})
    redirect_to inventory_items_url
  end
  ...

1 个答案:

答案 0 :(得分:1)

我个人将其提取到您的Product模型中:

class Product
  def self.first_or_create_by_params(params)
    # code here, return product
  end
end

然后在你的控制器中:

Product.first_or_create_by_params(params)