验证: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
答案 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
:
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。