2009-11-18 7 views
0

validate: check_product_stockaide de validation personnalisée nécessaire

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 

je dois être en mesure de valider la création d'un modèle (la vente), si elle est une association (produit), n'a pas atteint zéro dans un product.column appelé stock_number.

Je pense que j'ai besoin de réécrire le tout mais maintenant avec valider: check_product_stock puis construit une méthode à partir de zéro qui vérifie si le produit n'a pas atteint zéro et il doit le jeter un avis instantané et rester au même endroit (ventes/nouvelles)

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 

Et ceci est mon observateur qui diminue la colonne en_stock de 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 

Répondre

4

Il semble que vous ayez beaucoup de problèmes ici.

Tout d'abord, vous faites beaucoup trop de travail. C'est tout ce dont vous avez vraiment besoin.

before_save :check_product_stock 

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

Deuxièmement, le hachage flash n'est pas disponible dans les modèles. Vous pouvez utiliser l'objet d'erreur ActiveRecord pour faire des erreurs à la disposition du contrôleur et des vues en remplaçant

flash[:notice] = avec errors.add_to_base

je errors.add_to_base parce que l'erreur est pas exactement une partie de ce modèle, mais bloque toujours l'enregistrer. Troisièmement, il semble que vous réduisez product.stockNumber à un moment donné. Probablement comme before_validation, il est donc très possible que product.stocknumber soit inférieur à 0 lors de la vérification si product.stocknumber était 0 avant l'appel save.

Changeons donc la condition if pour refléter cela. Enfin, vous utilisez un rappel before_save, donc l'ajout d'une erreur n'annule pas la transaction. Vous devez retourner false pour un rappel avant/après save/create/update/valdiaiton pour annuler la transaction.

Mettre tout cela ensemble vous donne

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 

En ce qui concerne l'affichage de ces erreurs, vous pouvez utiliser l'aide de belle error_messages_for sur l'objet dans la vue. Ou copiez les erreurs dans le hachage flash du contrôleur.

De l'avis:

<%= error_mesages_for :order %> 

Ou, dans le contrôleur dans le bloc else de if @order.save:

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

Je préfère les erreurs sur avis quand il s'agit d'erreurs qui passent dans le hachage flash car il est facile de distinguer les deux via CSS si une action arrive à produire à la fois un avis ou une erreur. De plus, il est plus SEC de toujours afficher flash [: errors] avec une classe qui donne du texte en rouge, d'écrire la logique dans votre vue pour déterminer si le contenu de flash [: notice] est une erreur ou un avis.

2

flash n'est pas disponible dans le modèle. Vous devez faire quelque chose comme ceci:

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

Et puis travailler avec le flash dans le contrôleur et les vues.

+0

Je suis perdu, pouvez-vous aller plus loin dans ce domaine? merci d'avance, ce que je veux, c'est vérifier si une association (producto) au modèle principal (venta) n'a pas atteint zéro dans le champ en_stock. –

+0

Votre code est fondamentalement bien. Le seul problème est l'appel à flash [] qui n'est pas accessible dans un modèle ActiveRecord. La bonne façon de gérer les erreurs dans ActiveRecord est d'appeler errors.add. –

+0

si je fais: def check_product_stock @thisproduct = producto.id @productbeingchecked = Producto.find_by_id (@thisproduct) @stocknumber = @ productbeingchecked.en_stock si @stocknumber == 0 errors.add: Numéro de stockage , "Le produit n'existe pas existencias disponibles, por lo tanto pas puede completarse la venta." fin fin i get -1 en essayant de faire une vente avec un produit avec un stock en zéro, il est donc inutile –