【问题标题】:WHERE condition is invalid when trying to save尝试保存时 WHERE 条件无效
【发布时间】:2012-10-07 06:37:40
【问题描述】:

我正在开发一个使用多对多关系的 Rails 应用程序,它需要连接表上的额外属性(除了两个相关实体的 id)。

在模型中,一个产品可以属于多个订单,一个订单可以有多个产品。 所以我创建了一个将产品分配给给定订单的操作,称为add_product_order,并且在发送表单时处理表单的控制器方法是finish_add_product_order

def finish_add_product_order
  @order = Order.find(params[:id])
  @product = Product.find(params[:order][:products])

  if @op = OrdersProduct.find_by_order_id_and_product_id(@order.id, @product.id)
    @op.quantity = params['quantity'][0]
  else
    @op = OrdersProduct.new(:order => @order, :product => @product, :quantity => params['quantity'][0])
  end

  respond_to do |format|
    if @op.save
      format.html { redirect_to @order, notice: 'Order was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: "add_product_order", notice: 'No se ha podido grabar.' }
      format.json { render json: @order.errors, status: :unprocessable_entity }
    end
  end
end

orders_products 表(用于存储相关的 id 和数量)具有以下索引:

add_index :orders_products, [:order_id, :product_id], :unique => true

如果产品尚未在订单中(即正在调用 OrdersProduct.new),上述操作 (finish_add_product_order) 可以正常工作。 但这是我得到的错误,当它已经存在并且我尝试保存它时

SQLite3::SQLException: no such column: orders_products.: UPDATE "orders_products" SET "quantity" = 4 WHERE "orders_products"."" IS NULL

请求参数如下,以防万一:

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"TwPMk73MhCM2IeMfmf2g/fdm3+ahpyaxs1InULC/8ig=",
 "order"=>{"products"=>"4"},
 "quantity"=>["4"],
 "commit"=>"Update Order",
 "id"=>"2"}

我认为 WHERE 子句应该同时包含订单和产品 ID,以便识别受影响的行,但我不知道为什么不包含列名,也不知道为什么它以“IS NULL”结尾。

有什么建议吗?谢谢

编辑

这是涉及的三个类的代码:

class Order < ActiveRecord::Base
  belongs_to :user

  has_many :gardens, :dependent => :destroy

  has_many :products, :through => :orders_products
  has_many :orders_products

  attr_accessible :address, :delivery_date, :paid, :user, :orders_products_attributes

  # hid some irrelevant methods
end



class Product < ActiveRecord::Base
  has_many :gardens, :through => :gardens_products
  has_many :gardens_products

  has_many :orders, :through => :orders_products
  has_many :orders_products

  attr_accessible :cost, :description, :stock, :title, :x_size, :y_size, :pivot_x_position, :pivot_y_position, :is_gallery_product

  validates_presence_of :cost, :stock, :title, :x_size, :y_size, :pivot_x_position, :pivot_y_position
  validates_numericality_of :cost, :stock, :x_size, :y_size, :pivot_x_position, :pivot_y_position, :only_integer => true, :message => "Solo puede ser un numero entero"
  validates_inclusion_of :cost, :in => 0..1000000, :message => "Solo puede estar entre 0 y 1 000 000"
  validates_inclusion_of :stock, :in => 0..10000000, :message => "Solo puede estar entre 0 y 10 000 000"
  validates_inclusion_of :x_size, :y_size, :in => 1..200, :message => "Solo puede estar entre 0 y 200"
  # Poner el rango variable en los pivotes (dentro del rango del tamano)
  validates_inclusion_of :pivot_x_position, :in => 1..200, :message => "El pivote debe estar dentro de las dimensiones del producto"
  validates_inclusion_of :pivot_y_position, :in => 1..200, :message => "El pivote debe estar dentro de las dimensiones del producto"
  validates :title, :length => { :minimum => 5},
                            :presence => { :message => "Debe tener un titulo de largo mayor que 5 caracteres" }
end


class OrdersProduct < ActiveRecord::Base
  belongs_to :order, :dependent => :destroy
  belongs_to :product

  attr_accessible :order, :product, :quantity

  validates_numericality_of :quantity,
                            :only_integer => true,
                            :message => "solo puede ser un numero entero"
  validates_inclusion_of :quantity,
                            :in => 1..1000,
                            :message => "solo puede estar entre 1 y 1 000"
end

再次感谢

【问题讨论】:

    标签: ruby-on-rails ruby save where


    【解决方案1】:

    将这个查找调用“find_by_order_id_and_product_id”替换为“where”调用,并通过调用.first获取返回的Relation对象的第一个对象。

      if @op = OrdersProduct.where(:order_id => @order.id, :product_id => @product.id).first
        @op.quantity = params['quantity'][0]
      else
        @op = OrdersProduct.new(:order => @order, :product => @product, :quantity => params['quantity'][0])
      end
    

    如果有帮助,请告诉我。

    【讨论】:

    • 非常感谢Stone,我试过你的代码,但它给了我同样的错误SQLite3::SQLException: no such column: orders_products.: UPDATE "orders_products" SET "quantity" = 5 WHERE "orders_products"."" IS NULL。还有什么想法吗? :)
    • 你能贴出你的模型代码和其他任何东西吗?我需要更多信息以提供进一步帮助。
    • 我认识的人告诉我问题可能是连接表的每一行都没有 id(事实上,在创建它时,我在某处放置了 :id =&gt; :false),我将请继续阅读,稍后将在此处发布。
    • 是的,您需要连接表中的 order_id 和 product_id 才能工作。您还需要一个 id 列。
    【解决方案2】:

    由于在没有 id 的情况下创建了 orders_products 表(使用create_table :orders_products, :id =&gt; :false do |t|...),我所要做的就是在迁移中为其添加一个 id:

    class AddIdToOrdersProduct < ActiveRecord::Migration
      def change
        add_column :orders_products, :id, :primary_key
      end
    end
    

    这样,在做rake db:migrate之后它就起作用了。

    【讨论】:

      猜你喜欢
      • 2021-09-10
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      相关资源
      最近更新 更多