2016-04-06 16 views
1

商品がすでにバスケットに存在するかどうかを評価する論理を書こうとしています。ユーザーが商品を追加したときに商品数量を1ずつ増やし、新しいレコードビットを作成するとうまくいきます)。バスケットアイテムを増やすRuby

def create 
    @product = Product.find(params[:product_id]) 
    @basket = current_basket 

    if @basket.items.exists?(product_id: @product.id) 
     current_basket.items.find(conditions: {:product_id => @product.id}).increment! :quantity 
    else 
     Item.create!(basket_id: @basket.id, product_id: @product.id, quantity: 1, price: @product.price) 
    end 

    redirect_to baskets_show_path 

end 

私は取得していますエラーは、すべてのヘルプははるかに高く評価されるだろうSQLite3::SQLException: no such column: id.conditions: SELECT "items".* FROM "items" WHERE "items"."basket_id" = ? AND "id"."conditions" = '--- :product_id: 2 ' LIMIT 1

です。

答えて

1

find_by代わりの条件使用してみてください:

def create 
    @product = Product.find(params[:product_id]) 
    @basket = current_basket 

    if @basket.items.exists?(product_id: @product.id) 
     current_basket.items.find_by(product_id: @product.id).increment! :quantity 
    else 
     Item.create!(basket_id: @basket.id, product_id: @product.id, quantity: 1, price: @product.price) 
    end 

    redirect_to baskets_show_path 

end 
+0

私は文字通り 'find_by'を試していました。 –

1

first_or_createは役に立つかもしれません。 API Dock ActiveRecord::Relation first_or_createを参照してください。もちろん、項目には複数の識別基準があるため、ニーズは文書で提供されるものより複雑です。

私はオープンしているアプリのモデルでこれをテストしましたが、そのトリックをしているように見えました(実際の作成に失敗したと思われるので、モデルには多くの検証があります) 。

def create 
    @product = Product.find(params[:product_id]) 
    @basket = current_basket 

    item = Item.where({basket_id: @basket.id, 
        product_id: @product.id, 
        price:  @product.price}) 
      .first_or_create(quantity: 0) 
    item.increment! :quantity 

    redirect_to baskets_show_path 
end 

だから、基本的に何が起こっている、あなたはそれがあるかどうかごの項目に項目を設定し、またはそれはあなたがすでに求めていた情報だけでなく、ゼロの初期量ではない場合、それを作成します。次に、1だけインクリメントします。

もう1つの注意点は、両方のインスタンス変数が必要であることを確認することです。ビューに@basketだけが必要な場合は、すべての製品リファレンスから@を削除することを検討してください。コントローラをスキニー状態に保つ理由と方法の説明はJumpstart Lab's Slimming Controllersです。