现在我有三个型号:Product,Cart,CartItem。以下是相关的方法和关联:
cart.rb
class Cart < ApplicationRecord
has_many :cart_items
has_many :products, :through => :cart_items, :source => :product
cart_item.rb (它有2个相关的整数列,:product_id
&amp; :cart_id
)
class CartItem < ApplicationRecord
belongs_to :cart
belongs_to :product
application_controller.rb
class ApplicationController < ActionController::Base
helper_method :current_cart
def current_cart
@current_cart ||= find_cart
end
private
def find_cart
cart = Cart.find_by(id: session[:cart_id])
if cart.blank?
cart = Cart.create
end
session[:cart_id] = cart.id
return cart
end
end
在 carts_controller.rb 中我定义了一种方法来删除购物车中的特定cart_item #index page:
class CartsController < ApplicationController
def destroy_one
@cart_item = current_cart.cart_items.find_by_product_id(params[:id])
@product = @cart_item.product
@cart_item.destroy
redirect_to :back
在 destroy_one 方法的第一行,我可以使用find_by_product_id(params[:id])
来获取正确的cart_item
然后我尝试find_by(product_id: params[:id])
,它也有效。
但如果我使用find_by(params[:product_id])
,就会出现问题。当我点击删除按钮时,它不会引发异常,但会删除另一个cart_item。看来rails似乎随机选择了cart_item并将其删除。
显然,find_by(params[:product_id])
在这里工作不正确。
我的问题是:
在这种情况下,我对rails如何逐步找到正确的对象感到困惑?在一个购物车中,有许多cart_items和产品,使用:product_id
定位cart_item是合理的。但是有什么区别:
find_by_product_id(params[:id])
vs find_by(params[:product_id])
分别是如何运作的?
答案 0 :(得分:1)
问题在于您使用find_by(params[:product_id])
错误。你必须明确地传递你想要搜索的密钥:
find_by(product_id: params[:product_id])
User.find_by(id: 1)
-> User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
你可以按照你的说法分别使用它:
find_by_product_id(params[:product_id])
User.find_by_id(1)
-> User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
如您所见,这两种方法都会生成完全相同的SQL查询。