Rails を使用したアジャイル Web 開発 (バージョン 3) のものに基づいて、ショッピング カートを作成しています。「アイテム」が「カート」に追加される場所を設定してから、チェックアウトプロセスを開始すると、「注文」オブジェクトに「line_items」として追加されます。「line_items」は、任意の数量の 1 つの「アイテム」を表します。ここまでは、本の例から逸脱していません。ただし、ここで複雑になります。私の店のすべての「アイテム」はテキストでカスタマイズ可能であり、「注文」の「line_items」でカスタムテキストを保存できる必要があります。
前述のように、「line_items」には任意の数量の「item」が保持されますが、顧客はすべてのアイテムをカスタマイズできる必要があるため、各「line_item」は個々の「item」ごとに異なるカスタマイズを保持する必要があります。そのため、「line_items」テーブルにカスタマイズ用の列を 1 つだけにすることはできません。私がそれを整理することにした方法は、新しいモデル/テーブル「line_item_attributes」を作成することでした。「line_item」内の個々の「item」ごとに、新しい「line_item_attributes」があります。
私はまだ Rails を使い始めたばかりで、これを機能させるのに苦労しています。これを「正しい方法」で行っているとは確信していません。私が遭遇したのは、一種の鶏と卵の問題です。「注文」を作成するとき、カートから「アイテム」を「line_items」として追加します。彼らが注文している製品をカスタマイズするために、カスタマイズ フォームが機能するように、各「line_item」に「line_item_attributes」も追加する必要があります。
わからないことは次のとおりです。顧客がフォームを送信した後、空白の「line_item_attributes」に「記入」する方法がわかりません。フォームに「ダミー」の line_item_attributes を作成できず、送信時に、送信されたデータから新しいもの (実際に保存されるもの) を作成します。これは、それらが属する「line_items」に関連付ける必要があるためです。「@order.save」を呼び出したときにRailsがそれらを埋めてくれることを望んでいましたが、そうではありません。これが理解するのが難しくないことを願っています。
以下に関連するコードを含めました。
buy.rb (コントローラー)
-SNIP-
def purchase
@cart = find_cart
if @cart.items.empty?
redirect_to_index("Your order is empty")
end
end
def customize
@renderable_partials = [1, 2, 3]
@order = find_order
if @order.nil?
redirect_to_index("Your order is empty")
end
end
def save_purchase
@cart = find_cart
@order = find_order(params[:cart_owner])
@order.add_line_items_from_cart(@cart)
redirect_to :action => 'customize'
end
def save_customize
@order = find_order
if @order.save
redirect_to :action => 'purchase'
else
flash[:error] = "Your information could not be saved"
redirect_to :action => 'customize'
end
end
-SNIP-
order.rb (モデル)
class Order < ActiveRecord::Base
has_many :line_items
has_many :line_item_attributes
accepts_nested_attributes_for :line_items
accepts_nested_attributes_for :line_item_attributes
def add_line_items_from_cart(cart)
cart.items.each do |item|
li = LineItem.from_cart_item(item)
line_items << li
end
end
end
line_item.rb (モデル)
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :item
has_many :line_item_attributes
accepts_nested_attributes_for :line_item_attributes
def self.from_cart_item(cart_item)
li = self.new
li.item = cart_item.item
li.quantity = cart_item.quantity
li.total_price = cart_item.price
li.quantity.times do |single_item|
lia = LineItemAttribute.new
li.line_item_attributes << lia
end
li
end
end
line_item_attributes.rb (モデル)
class LineItemAttribute < ActiveRecord::Base
belongs_to :order
belongs_to :line_item
end
助けてくれてありがとう!