2

多対多の関係を使用するRailsアプリケーションを開発しています。これには、結合テーブルに追加の属性が必要です(2つの関連するエンティティの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

上記のアクション(finish_add_product_order)は、製品がまだ注文に含まれていない場合(つまりOrdersProduct.new、呼び出されている場合)に正常に機能します。しかし、これは私がすでに存在しているときに私が得るエラーであり、私はそれを保存しようとします

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の両方を含める必要があると思いますが、列名が含まれていない理由も、「ISNULL」で終わる理由もわかりません。

助言がありますか?ありがとう

編集

これは、関連する3つのクラスのコードです。

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

再度、感謝します

4

2 に答える 2

0

この検索呼び出し " find_by_order_id_and_product_id" を " "呼び出しに置き換え、 を呼び出しwhereて、返されたRelationオブジェクトの最初のオブジェクトを取得します。first.

  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

それが役立つかどうか教えてください。

于 2012-10-07T07:09:28.977 に答える
0

orders_products テーブルは id なしで( でcreate_table :orders_products, :id => :false do |t|...)作成されていたので、この移行で id を追加するだけで済みました。

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

そのように、それはやった後に働いた rake db:migrate

于 2012-10-08T03:01:12.063 に答える