小控制器上的代码重构(瘦控制器胖模型)

时间:2013-12-16 12:00:37

标签: ruby-on-rails ruby

我有一个控制器操作正在进行产品列表,分页和一些过滤器,例如类别(来自下拉列表),标题(来自文本字段),库存(来自复选框) 这是我的控制者:

  class ProductsController < ApplicationController
  def index
    @products = Product.where(active:1).where("title LIKE ?","%#{params[:title]}%")
      if params[:stock]
        @products=@products.where("stock = 0")
      end
      if params[:category] 
        @products=@products.where("category_id LIKE ?","#{params[:category]}")
      end
    @products= @products.paginate(:page => params[:page])
    @categories= Category.all
  end

我的模特是:

class Product < ActiveRecord::Base
  belongs_to :category
    ...some validations...
end

为了让控制器变得更薄,我可以改变什么?感谢

4 个答案:

答案 0 :(得分:2)

我提出了具体的重构风格:

<强>控制器

class ProductsController < ApplicationController
   def index
      @products = Product.titled params[:title]
      @products = @products.in_stock if params[:stock]
      @products = @products.category params[:category] if params[:category]

      @products = @products.paginate :page => params[:page]
      @categories = Category.all
   end
end

<强>模型

class Product < ActiveRecord::Base
   belongs_to :category
   ...
   scope :titled, proc {| title | where(active:1).where("title LIKE ?","%#{title}%")
   scope :in_stock, proc { where("stock = 0") }
   scope :category, proc {| category | where("category_id LIKE ?","#{category}") }
end

答案 1 :(得分:2)

模型

class Product < ActiveRecord:::Base
  scope :active, where(active: 1)

  def self.with_stock(stock=nil)
    return where(stock: 0) if stock
    self
  end

  def self.categorized(category=nil)
    return self.where(category: category) if category
    self
  end

  def self.titled(title=nil)
    return self.where("title LIKE ?", 'title') if title
    self
  end

  def self.list(params)
    title    = params[:title]
    category = params[:category]
    page = params[:page]
    self.titled(title).with_stock(stock).categorized(category)
      .paginate(page).active
  end
end

控制器

 def index
   @products = Product.list(params)
 end

请勿在控制器中运送类别。在模板/部分中执行。仅来自控制器的一个实例变量。

答案 2 :(得分:1)

如果您的意图只是让控制器变得更薄,您可以将逻辑移动到模型。

ProductController.rb

@products = Product.some_method(params)

Product.rb

def self.some_method(params)
  if params[:stock]
    where("stock = 0 AND active  = 1 AND title LIKE ?","%#{params[:title]}%")
  end
  if params[:category] 
    where("active = 1 AND category_id LIKE ? AND title LIKE ?", "#{params[:category]}", "%#{params[:title]}%")
  end

答案 3 :(得分:1)

使用瘦控制器,脂肪模型原理。

<强>控制器

class ProductsController < ApplicationController
  def index
    @products = Product.active(params).paginate(page: params[:page])
    @categories = Category.all
  end
end

<强>模型

class Product < ActiveRecord::Base
  belongs_to :category

  def self.active(params)
    products = where(active:1).where("title LIKE ?","%#{params[:title]}%")
    if params[:stock]
      products = products.where("stock = 0")
    end
    if params[:category]
      products = products.where("category_id LIKE ?","#{params[:category]}")
    end
  end
end