需要自定义验证帮助

发布于 2024-08-11 18:06:21 字数 3702 浏览 4 评论 0原文

验证: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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月亮邮递员 2024-08-18 18:06:21

看来你这里出了很多问题。

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

before_save :check_product_stock

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

其次,闪存哈希在模型中不可用。 替换为 errors.add_to_base 来使错误可用于控制器和视图。

您可以使用 ActiveRecord 错误对象,通过将flash[:notice] =

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

第三,您似乎在某个时候减少了product.stocknumber。可能作为 before_validation,因此在保存调用之前,如果 Product.stocknumber 为 0,则在检查期间,product.stocknumber 很可能小于 0。

因此,让我们更改 if 条件来反映这一点。

unless product.stocknumber > 0

最后,您使用的是 before_save 回调,因此仅添加错误不会取消事务。您需要在保存/创建/更新/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

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

在视图中:

<%= error_mesages_for :order %>

或者,在 if @order.save 的 else 块中的控制器中:

 flash[:errors] = @order.errors.full_messages.join "<br />"

当涉及到在 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.

before_save :check_product_stock

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

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] = with errors.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.

unless product.stocknumber > 0

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

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

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:

<%= error_mesages_for :order %>

Or, in the controller in the else block of if @order.save:

 flash[:errors] = @order.errors.full_messages.join "<br />"

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.

很酷又爱笑 2024-08-18 18:06:21

该型号不支持闪光灯。您需要执行以下操作:

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

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

flash is not available in the model. You need to do something like this:

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

And then work with flash in the controller and views.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文