【问题标题】:refactoring from controller to model从控制器重构为模型
【发布时间】:2012-09-16 18:10:37
【问题描述】:

我的订单控制器中有此操作:

# POST /orders
# POST /orders.json
def create
  @order = Order.new(params[:order])

  #spostare il ciclo cart > line_items come metodo del modello Order
  cart = session[:cart]

  cart.each do | id, quantity |
    item = Project.find_by_id(id)
    @line_item = LineItem.new
    @line_item.project = item
    @line_item.quantity = quantity
    @line_item.price = item.price
    @order.line_items << @line_item
  end

  @order.user = current_user

  session.delete(:cart)

  respond_to do |format|
    if @order.save
      #Send an email to admin
      UserMailer.order_created_to_admin(@order).deliver

      format.html { redirect_to :dashboard, notice: "L'ordine è stato creato correttamente." }
      format.json { render json: @order, status: :created, location: @order }
    else
      format.html { render action: "new" }
      format.json { render json: @order.errors, status: :unprocessable_entity }
    end
  end
end

现在我想对其进行一些重构,我正在考虑将以下几行作为方法移至 Order Model:

  cart.each do | id, quantity |
    item = Project.find_by_id(id)
    @line_item = LineItem.new
    @line_item.project = item
    @line_item.quantity = quantity
    @line_item.price = item.price
    @order.line_items << @line_item
  end

这样:

class Order < ActiveRecord::Base
  attr_accessible :user_id

  belongs_to :user
  has_many :line_items, :dependent => :destroy
  accepts_nested_attributes_for :line_items, :allow_destroy => true

  def add_line_items_to_order_from_cart(cart) do
    cart.each do | id, quantity |
      item = Project.find_by_id(id)
      @line_item = LineItem.new
      @line_item.project = item
      @line_item.quantity = quantity
      @line_item.price = item.price
      line_items << @line_item
    end
  end
end

并从控制器调用它,例如:

order.add_line_items_to_order_from_cart(cart)

就“瘦控制器/胖模型”模式而言是否有意义?

谢谢

编辑

我的订单模型现在:

class Order < ActiveRecord::Base
  attr_accessible :user_id

  belongs_to :user
  has_many :line_items, :dependent => :destroy
  accepts_nested_attributes_for :line_items, :allow_destroy => true
  validates :user, :presence => :true

  def add_line_items_to_order_from_cart(cart)
    cart.each do | id, quantity |
      item = Project.find(id)
      line_items << LineItem.new(project: item,
                                 quantity: quantity,
                                 price: item.price)
    end
  end

end

【问题讨论】:

  • 是的,这真的很有意义!我是“瘦控制器/胖模型”模式的粉丝 :)
  • 嗨@BlueSmith,谢谢!我在想所有对其他模型 Project 和 LineItems 的“调用”都可能是模型内部的问题。

标签: ruby-on-rails ruby ruby-on-rails-3 refactoring


【解决方案1】:

对我来说很有意义,您正在为模型提供哈希,而模型负责解析哈希并将其转换为数据库记录。

甚至可以将整个 line_item 内容移到一行中,这样更简洁:

def add_line_items_to_order_from_cart(cart) do
  cart.each do |id, quantity|
    item = Project.find_by_id(id)
    line_items << LineItem.new( project: item,
                                quantity: quantity,
                                price: item.price )
  end
end

你甚至可以这样尝试:

def add_line_items_to_order_from_cart(cart) do
  line_items = cart.map do |id, quantity|
    item = Project.find_by_id(id)
    LineItem.new( project: item,
                  quantity: quantity,
                  price: item.price )
  end
end

但总体思路是正确的,将这些东西移到模型中! ;)

【讨论】:

  • 使用line_items &lt;&lt; LineItem.new project: item, quantity: quantity, price: item.price 我得到syntax error, unexpected tLABEL, expecting keyword_end (SyntaxError) ..._items &lt;&lt; LineItem.new project: item, quantity: quantity, pr...
  • 第 4 行是语法错误。传递 LineItem.new 时需要使用括号。
  • 嗯不认为在这种情况下它们是必要的,但让我们添加它们以确保。 ;)
猜你喜欢
  • 2011-06-19
  • 1970-01-01
  • 2015-01-06
  • 2012-03-29
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多