1

解決策については、以下のアップデート 1 & 2 を参照してください

「Rails を使用したアジャイル Web 開発」という本のショッピング カートの作成に関するチュートリアルに従っています。 .pdf

本では、この行<%= button_to 'Add to Cart', line_items_path(product_id: product) %>を使用して、カートに渡されてセッションに保存されるline_item を作成する必要があります。 to <%= button_to '', line_items_path(gear_id: ギア), id: 'rent_it' %>

これを変更して、他のパラメーターも受け入れるフォームにしたい場合は、どうすればよいですか?

以下は、私が使用してこれを達成しようとしたコードですが、これまでのところ成功していません。以下のコードでは、「id」がないとギアが見つからないというエラーが表示されます。私はレールとプログラミング全般に不慣れなので、助けていただければ幸いです。

UPDATE 1(以下のビューも更新しました)

サーバー ログから、Gear の ID をフォームで渡していることがわかります。これは私が最初にやろうとしていたことです。

Processing by LineItemsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"0QnJShABOV+avPx0AJHxuMmskfwtwFlkpMa6cBhTU3s=", "line_item"=>{"rentstart"=>"", "rentend"=>"", "gear_id"=>"13"}, "commit"=>""}
  Cart Load (0.4ms)  SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = 18 LIMIT 1
Completed 500 Internal Server Error in 2ms

ActiveRecord::RecordNotFound (Couldn't find Gear without an ID):
  app/controllers/line_items_controller.rb:44:in `create'

ID のないギアが見つかりませんでしたというエラーが引き続き表示されます。以下の2行はどれですか:

    gear = Gear.find(params[:gear_id])
    @line_item = @cart.add_gear(gear.id)

私は何が欠けていますか?

ラインアイテムのコントローラー

  def create
    @cart = current_cart
    gear = Gear.find(params[:gear_id])
    @line_item = @cart.add_gear(gear.id)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to @line_item.cart }
        format.json { render json: @line_item, status: :created, location: @line_item }
      else
        format.html { render action: "new" }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

カートモデル

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy

  def add_gear(gear_id)
    current_item = line_items.find_by_gear_id(gear_id)
    if current_item
      current_item.quantity += 1
    else
      current_item = line_items.build(params[:line_item])
    end
    current_item
  end

  def total_price
    line_items.to_a.sum { |item| item.total_price }
  end

end

ギアショーページから見る

<div class="gearside_date_main">
        <h3>Rental Date</h3>
        <script>
        $(function() {
            var dates = $( "#rentstart, #rentend" ).datepicker({
                defaultDate: "+1w",
                changeMonth: true,
                numberOfMonths: 1,
                onSelect: function( selectedDate ) {
                    var option = this.id == "rentstart" ? "minDate" : "maxDate",
                        instance = $( this ).data( "datepicker" ),
                        date = $.datepicker.parseDate(
                            instance.settings.dateFormat ||
                            $.datepicker._defaults.dateFormat,
                            selectedDate, instance.settings );
                    dates.not( this ).datepicker( "option", option, date );
                }
            });
        });
        </script>


    <%= form_for LineItem.new do |f| %>
        <%= f.text_field :rentstart, id: 'rentstart'  %>
        <%= f.text_field :rentend, id: 'rentend'  %>
        <%= f.hidden_field :gear_id, :value => @gear.id %>
        <%= f.submit "", id: 'rent_it' %>
    <% end %>
        <% end %>
    </div>

更新 2

Murifoxのコメントの後、ようやく機能しました。ハッシュを渡すときの構文がどのように構成されているかを完全には理解していませんでした。そのため、多くの試行錯誤の末、機能しています。行った変更を確認するために、更新したコードを以下に含めます。答えを見ると、いつも変化を探しています。これが他の誰かに役立つことを願っています....

ビュー(ギアショーページ

<%= form_for LineItem.new do |f| %>
    <%= f.text_field :rentstart, id: 'rentstart'  %>
<%= f.text_field :rentend, id: 'rentend'  %>
<%= f.hidden_field :gear_id, :value => @gear.id %>
    <%= f.submit "", id: 'rent_it' %>
<% end %>

コントローラー (アクションの作成)

  def create
    @cart = current_cart
    gear = Gear.find(params[:line_item][:gear_id])
    lineitem = params[:line_item]
    @line_item = @cart.add_gear(lineitem, gear.id)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to @line_item.cart }
        format.json { render json: @line_item, status: :created, location: @line_item }
      else
        format.html { render action: "new" }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

カートモデル

  def add_gear(lineitem, gear_id)
    current_item = line_items.find_by_gear_id(gear_id)
    if current_item
      current_item.quantity += 1
    else
      current_item = line_items.build(lineitem)
    end
    current_item
  end
4

1 に答える 1

1

使ってみてください

gear = Gear.find(params[:line_item][:gear_id])
于 2012-06-06T20:18:28.023 に答える