【问题标题】:What the difference between find_by_product_id(params[:id]) vs find_by(params[:product_id])find_by_product_id(params[:id]) 与 find_by(params[:product_id]) 有什么区别
【发布时间】:2017-10-13 10:53:48
【问题描述】:

现在我有三个模型: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 & :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 中,我定义了一种删除 carts#index 页面中特定 cart_item 的方法:

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_item 和products,使用:product_id 定位cart_item 是合理的。但是有什么区别:

find_by_product_id(params[:id])find_by(params[:product_id])

分别是如何工作的?

【问题讨论】:

    标签: sql ruby-on-rails database


    【解决方案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 查询。

    【讨论】:

    • 谢谢 Philipp,在阅读了 Rails 指南并做了几次实验之后,我现在可以理解你所说的了。问题是我误解了 rails 检索数据的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多