2009-11-18 3 views
0

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 

мне нужно, чтобы иметь возможность проверить на создание модели (продажи), если это объединение (продукт), не дошел до нуля в product.column называемый ссылочным номером.

Я думаю, мне нужно переписать всю вещь, но теперь с проверкой: 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 

И это мой наблюдатель, который уменьшает столбец en_stock из 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 

ответ

4

Кажется, у вас здесь много чего не так.

Прежде всего, вы делаете слишком много работы. Это все, что вам действительно нужно.

before_save :check_product_stock 

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

Во-вторых, хэш-память вспышки недоступна в моделях. Вы можете использовать объект ActiveRecord ошибки делать ошибки, доступные для контроллера и представления, заменив

flash[:notice] = с errors.add_to_base

я использовал errors.add_to_base потому что ошибка не является именно частью этой модели, но все еще блокирует сохранить.

В-третьих, похоже, что вы уменьшаете номер продукта.stocknumber в какой-то момент. Вероятно, как раньше, так что очень возможно, что product.stocknumber меньше 0 во время проверки, если product.stocknumber был равен 0 перед вызовом сохранения.

Итак, давайте изменим условие if, чтобы это отразить.

unless product.stocknumber > 0 

Наконец, вы используете обратный вызов before_save, поэтому просто добавление ошибки не отменяет транзакцию. Для отмены транзакции необходимо вернуть false для обратного вызова до/после сохранения/создания/обновления/valdiaiton.

Сведя все это вместе дает

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:

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

Я предпочитаю ошибки более уведомления, когда речь идет о проходящих ошибок в флэш-хэш потому что это позволяет легко различать два через CSS, если происходит действие, которое вызывает как уведомления, так и ошибку. Также более DRY всегда отображает флэш [: errors] с классом, который дает красный текст, записывает логику в ваше представление, чтобы определить, является ли содержимое флэш [: notice] ошибкой или уведомлением.

2

вспышка недоступна в модели. Вам нужно сделать что-то вроде этого:

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

А затем работайте со вспышкой в ​​контроллере и просмотрите.

+0

Я потерян, не могли бы вы углубиться в это? спасибо заранее, что я хочу проверить, не связано ли объединение (producto) с основной моделью (venta) в поле en_stock равным нулю. –

+0

Ваш код в основном в порядке. Единственная проблема - вызов flash [], который недоступен в модели ActiveRecord. Правильный способ обработки ошибок в ActiveRecord - вызвать errors.add. –

+0

если я делаю: Защиту check_product_stock @thisproduct = producto.id @productbeingchecked = Producto.find_by_id (@thisproduct) @stocknumber = @ productbeingchecked.en_stock если @stocknumber == 0 errors.add: stocknumber , «Распределенные единицы диссиденций, которые не могут быть дополнены». конец конец я получаю -1 при попытке совершить продажу с продуктом с запасом в ноль, так что это бессмысленно –

Смежные вопросы