需要自定义验证帮助

时间:2009-11-18 02:14:11

标签: ruby-on-rails validation hobo

验证:check_product_stock

def check_product_stock

  @thisproduct = product.id

   @productbeingchecked = Product.find_by_id(@thisproduct)

   @stocknumber = @productbeingchecked.stock_number

  if producto.en_stock == 0
   raise "El Producto no tiene stock suficiente para completar la venta"

   #errors.add :venta, "Producto con pedos de stock"
   return false
  end
true
end

end

我需要能够验证模型(销售)的创建,如果它的关联(产品),在名为stock_number的product.column中没有达到零。

我认为我需要重写整个事情,但现在使用validate:check_product_stock然后从头开始构建一个方法,检查产品是否未达到零并且它有它应该抛出闪光通知并保持在同一个地方(销售/新)

class Venta < ActiveRecord::Base

  hobo_model # Don't put anything above this

  belongs_to :cliente, :accessible => true
  belongs_to :producto, :accessible => true
  belongs_to :marca, :accessible => true
  belongs_to :vendedor
  belongs_to :instalador
  has_many :devolucions



  fields do
    numero_de_serie     :string
    precio_de_venta      :integer
    precio_de_instalacion :integer, :default => "0"
    forma_de_pago enum_string(:contado, :tarjeta)
    status enum_string(:activa, :cancelada)
    timestamps
  end

  validates_presence_of :cliente, :precio_de_venta, :vendedor, :precio_de_instalacion

  validate_on_create :check_product_stock

  after_save :descontar_precio_de_instalacion_si_el_instalador_es_a_destajo

#def stock_error

  #flash[:notice] = "Producto con pedos de stock"

#  redirect_to :controller => :venta, :action => :stock_error

     #errors.add_to_base("Producto con pedos de stock") 

 # end

def check_product_stock

if producto.en_stock == 0
 raise "El Producto no tiene stock suficiente para completar la venta"

 #errors.add :venta, "Producto con pedos de stock"
   return false
  end
true
end

#def check_product_stock
#  if producto.en_stock == 0
 #  errors.add :producto, "El Producto no tiene stock suficiente para completar la venta"
 #  return false
#  end
#  true # guards against returning nil which is interpreted as false.
#end




def descontar_precio_de_instalacion_si_el_instalador_es_a_destajo





  @este_instalador_id = instalador.id

  @instalador = Instalador.find_by_id(@este_instalador_id)


  if @instalador.a_destajo?

    @last_venta = Venta.find(:last)

    @vid = @last_venta.id

    @precio_de_instalacion_original = precio_de_instalacion

    @mitad_de_instalacion = @precio_de_instalacion_original/2

    #Venta.update(@vid, :precio_de_instalacion => @mitad_de_instalacion)

    ActiveRecord::Base.connection.execute "UPDATE ventas SET precio_de_instalacion = #{@mitad_de_instalacion} WHERE id = #{@vid};"



  end


end








#after_save :reduce_product_stock_number

# def reduce_product_stock_number
 #  Producto.decrement_counter(:en_stock, producto.id)
#  end




  # --- Permissions --- #

  def create_permitted?
    true
  end

  def update_permitted?
    false
  end

  def destroy_permitted?
    false
  end

  def view_permitted?(field)
    true
  end

end

这是我的观察者,它减少了producto的en_stock列:

class VentaObserver < ActiveRecord::Observer

def after_save(venta)

      @venta_as_array = venta




      if venta.producto_id?

      @pid = @venta_as_array[:producto_id]

      Producto.decrement_counter(:en_stock, @pid)

      end

      if venta.cart_id

        @cid = @venta_as_array[:cart_id] 

        @cart = Cart.find_by_id(@cid)  

        for item in @cart.cart_items do
         #  @pid = @cart.cart_items.producto.id



             Producto.decrement_counter(:en_stock, item.producto.id)

        end

        #si el instalador es a destajo se debe descontar la mitad del rpecio de instalacion






        end

end

end

2 个答案:

答案 0 :(得分:4)

看来你在这里遇到了很多错误。

首先,你做的工作太多了。这就是你真正需要的。

before_save :check_product_stock

def check_product_stock
  if product.stocknumber == 0
   flash[:notice] = "Producto con pedos de stock"
  end
end

其次,模型中没有flash哈希值。您可以使用ActiveRecord错误对象通过替换

使控制器和视图可用的错误 带有flash[:notice] =

errors.add_to_base

我使用了errors.add_to_base,因为错误并不是此模型的一部分,但仍然阻止了保存。

第三,似乎你在某种程度上减少了product.stocknumber。可能作为before_validation,因此如果product.stocknumber在保存调用之前为0,那么product.stocknumber很可能在检查期间小于0。

所以让我们改变if条件来反映这一点。

unless product.stocknumber > 0

最后,您正在使用before_save回调,因此只添加错误不会取消该事务。您需要为save / create / update / valdiaiton回调之前/之后返回false以取消事务。

把这一切放在一起就可以了

before_save :check_product_stock

def check_product_stock
  unless product.stocknumber > 0
   errors.add_to_base "Producto con pedos de stock"
   return false
  end
  true # guards against returning nil which is interpreted as false.
end

至于显示这些错误,您可以在视图中的对象上使用nice error_messages_for帮助器。或者将错误复制到控制器中的flash哈希。

在视图中:

<%= error_mesages_for :order %>

或者,在if @order.save

的else块中的控制器中
 flash[:errors] = @order.errors.full_messages.join "<br />"

当涉及到在flash哈希中传递错误时,我更喜欢错误而不是通知,因为如果一个动作碰巧产生通知或错误,它可以很容易地通过CSS区分两者。另外,总是使用提供红色文本的类显示flash [:errors],在视图中写入逻辑以确定flash [:notice]的内容是错误还是通知更为干燥。

答案 1 :(得分:2)

模型中没有闪光灯。你需要做这样的事情:

errors.add :stocknumber, "Producto con pedos de stock"

然后在控制器和视图中使用flash。