需要自定义验证帮助
验证: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
validate :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
i need to be able to validate on creation of a model (sale), if it's association (product), hasn't reached zero in a product.column called stock_number.
i think i need to rewrite the entire thing but now with validate :check_product_stock then built a method from scratch that checks if product hasn't reached zero and it it has it should throw a flash notice and stay in the same place (sales/new)
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
And this is my observer that diminishes the en_stock column from producto:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看来你这里出了很多问题。
首先,你做的工作太多了。这就是您真正需要的。
其次,闪存哈希在模型中不可用。 替换为
errors.add_to_base
来使错误可用于控制器和视图。您可以使用 ActiveRecord 错误对象,通过将
flash[:notice] =
我使用了errors.add_to_base,因为错误不完全是该模型的一部分,但仍然阻止保存。
第三,您似乎在某个时候减少了product.stocknumber。可能作为 before_validation,因此在保存调用之前,如果 Product.stocknumber 为 0,则在检查期间,product.stocknumber 很可能小于 0。
因此,让我们更改 if 条件来反映这一点。
最后,您使用的是 before_save 回调,因此仅添加错误不会取消事务。您需要在保存/创建/更新/valdiaiton 回调之前/之后返回 false 才能取消事务。
将所有这些放在一起就可以为您提供
至于显示这些错误,您可以在视图中的对象上使用很好的 error_messages_for 帮助器。或者将错误复制到控制器中的闪存哈希中。
在视图中:
或者,在
if @order.save
的 else 块中的控制器中:当涉及到在 Flash 哈希中传递错误时,我更喜欢错误而不是通知,因为它可以轻松区分如果某个操作碰巧同时产生通知或错误,则通过 CSS 实现两者。另外,始终使用提供红色文本的类显示 flash[:errors] 更加干燥,将逻辑写入视图中以确定 flash[:notice] 的内容是错误还是通知。
It seems you've got a lot going wrong here.
First of all, you're doing way too much work. This is all you really need.
Secondly, the flash hash is not available in models. You can use the ActiveRecord error object to make errors available to the controller and views by replacing
flash[:notice] =
witherrors.add_to_base
I used errors.add_to_base because the error is not exactly a part of this model, yet is still blocking the save.
Thirdly, it seems like you're reducing product.stocknumber at some point. Probably as a before_validation so it's highly possible that product.stocknumber is less than 0 during the check if product.stocknumber was 0 before the save call.
So let's change the if condition to reflect that.
Finally, you're using a before_save callback, so just adding an error will not cancel the transaction. You need to return false for a before/after save/create/update/valdiaiton callback to cancel the transaction.
Putting this all together gives you
As for displaying these errors you can either use the nice error_messages_for helper on the object in the view. Or copy the errors to the flash hash in the controller.
In the view:
Or, in the controller in the else block of
if @order.save
:I prefer the errors over notice when it comes to passing errors in the flash hash because it makes it easy to distinguish the two via CSS if an action happens to produce both a notices or an error. Also it's more DRY to always display flash[:errors] with a class that gives red text, the write the logic into your view to determine if the contents of flash[:notice] are an error or a notice.
该型号不支持闪光灯。您需要执行以下操作:
然后在控制器和视图中使用 Flash。
flash is not available in the model. You need to do something like this:
And then work with flash in the controller and views.