【问题标题】:link_to with nested routes within looplink_to 与循环内的嵌套路由
【发布时间】:2014-11-23 04:22:37
【问题描述】:

我正在为此苦苦挣扎,看起来应该很简单 - 我只是不明白为什么它不起作用。

我的付款视图中有以下循环,我想链接_以删除和编辑。 我传入了@bill 对象和 past_payment 对象。

我收到此错误:没有路由匹配 {:action=>"edit", :bill_id=>11, :controller=>"payments", :id=>nil} 缺少必需的键:[:id]

我不明白为什么我无法从 past_payment 中获取 :id。我尝试使用 past_payment.id 并通过将其打印为表的一部分来确保它存在于对象上。如果我静态输入一个 id 似乎可以工作。

  <div class="row">
  <div class="col-md-6">
    <h4>Payment for : <%=  @bill.vendor.full_vendor %></h4>
    <p>Amount Owing: <%= humanized_money_with_symbol @bill.owing %></p>
    <p>Due: <%=  @bill.due_date.to_formatted_s(:rfc822) %> </p>
  </div>

  <div class="col-md-6">
    <h4>Payment Options</h4>
    <table class="table table-striped table-responsive">
      <tr>
        <td><%=image_tag("40px_BPAY_2012_PORT_BLUE.png", alt: "BPay_Image")%></td>
        <td><p>biller code:</br><%=  @bill.vendor.bpay_biller_code %></p></td>
        <td><p>ref number:</br><%=  @bill.vendor.bpay_ref %></p></td>
      </tr>
    </table>
  </div>

</div>

<div class="row col-md-12">
  <h4>This Payment</h4>
</div>

  <%= form_for(@payment, url: :bill_payments, html: { method: "post", class: "form-horizontal", role: "form" } ) do |payment| %>

    <div class="form-group col-md-12">
      <%= payment.label :amount, class: "control-label sr-only" %>
      <%= payment.text_field :amount, data: { role: 'money', aSign: '$'}, class: "form-control", placeholder: "Amount Paid"  %>

      <%= payment.label :receipt_number, class: "control-label sr-only" %>
      <%= payment.text_field :receipt_number, class: "form-control", placeholder: "Receipt #" %>

      <%= payment.label :notes, class: "control-label sr-only" %>
      <%= payment.text_area :notes, class: "form-control", rows: "1", placeholder: "Notes"  %>

      <div class="form-inline">
      <%= payment.label :payment_date, class: "control-label sr-only" %>
      <%= payment.date_select :payment_date, { order: [ :day, :month, :year ],
        start_year: 2014,
        end_year:2020 },
        class: "form-control" %>
      </div>
    </div>

  <%= payment.submit "Pay", class: "btn btn-default" %>
  <% end %>


</br>
<div class="row">
  <div class="col-md-12">
    <h4>Previous Payments</h4>
      <table class="table table-striped table-responsive">
        <tr>
          <th>Amount Paid</th>
          <th>Receipt #</th>
          <th>Date Paid</th>
          <th colspan="2">Actions</th>
      </tr>
      <% @bill.payments.each do |past_payment| %>
        <tr>
          <td><p><%= humanized_money_with_symbol past_payment.amount %></p></td>
          <td><p><%=  past_payment.receipt_number %></p></td>
          <td>
            <% if not past_payment.payment_date == nil %>
              <p><%=  past_payment.payment_date.to_formatted_s(:rfc822) %></p>
            <% end %>
            </td>
 -->        <td>
              <%= link_to "Edit", edit_bill_payment_path(@bill, past_payment), method: :patch %>
            </td>
            <td>
              <%= link_to "Delete", bill_payment_path(@bill, past_payment), method: :delete,
 -->               data: { confirm: "Are you sure?" } %>
            </td>
        </tr>
      <% end %>
      </table>
   </div>
 </div>

控制器代码

class PaymentsController < ApplicationController
  before_action :authenticate_user!


  def new
    @bill=Bill.find(params[:bill_id])
    @payment=@bill.payments.new
  end

  def edit
    @bill=Bill.find(params[:bill_id])
    @payment=@bill.payments.find(:id)
  end

  def update
    @bill=Bill.find(params[:bill_id])
    if @bill.payments(payment_params).update
      flash[:success] = "This payment has been updated"
      redirect_to new_bill_payment_url(params[:bill_id])
    else
      flash[:error] = "There has been a problem updateing this payment"
      redirect_to :back
    end
  end

  def create
      @bill=Bill.find(params[:bill_id])
     if @bill.payments.save
      flash[:success] = "This payment has been registered"
      redirect_to new_bill_payment_url(params[:bill_id])
    else
      flash[:error] = "There has been a problem with this payment"
      redirect_to :back
    end
  end

  def destroy
    @bill=Bill.find(params[:bill_id])

    if @bill.payments.find(params[:id]).destroy
      flash[:success] = "This payment has been removed"
      redirect_to new_bill_payment_url(params[:bill_id])
    else
      flash[:error] = "There has been a problem removing this payment"
      redirect_to :back
    end
  end


private

  def payment_params
    params.require(:payment).permit(:id, :bill_id,:receipt_number, :notes, :amount,
                                                :payment_date)
  end

end

路由片段

resources :bills do
  resources :payments, only: [:new, :create, :edit, :destroy]
end

比尔模型

class Bill < ActiveRecord::Base

  belongs_to :user
  belongs_to :vendor
  has_many :payments, dependent: :destroy
  accepts_nested_attributes_for :payments, allow_destroy: true

  validates :vendor_id, :amount, :due_date, :bill_type, presence: true
  validate :over_payment

  monetize :amount_cents
  monetize :gst_cents
  monetize :owing_cents

  def owing_cents
    self.amount_cents - self.payments.sum(:amount_cents)
  end

  def gst_cents
    self.amount_cents/11
  end

private
  def over_payment
    if self.payments.sum(:amount_cents) > owing_cents
      errors.add(:amount, "Over payment of a bill not allowed
        add interest or penitalties as a negitive payment first")
    end
  end
end

感谢您的帮助。

【问题讨论】:

  • 你能从你的路线中给出sn-ps吗?
  • 请分享正在初始化@bill 的控制器代码。
  • 这个错误是由new 操作引发的吗?
  • 感谢@blelump 我添加了完整视图。是的,它是由new 操作驱动的
  • 你检查过你的表格吗?看起来您也可能缺少 bill 变量:

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

在动作中你到处都使用@bill=Bill.find(params[:bill_id]),但@bill 有一个:id,而不是:bill_id。这就是问题。你真正想要的是使用@bill=Bill.find(params[:id])

你使用的链接:&lt;%= link_to "Pay", new_bill_payment_path(bill) %&gt;给你:id=&gt;nil,因为没有bill对象,但是@bill,因此链接很可能应该是&lt;%= link_to "Pay", new_bill_payment_path(@bill) %&gt;

【讨论】:

  • 谢谢 Andrey - 支付控制器中的新操作从以下位置调用:` ` 它的路径通过 bill_id
  • 它必须是` ` 然后
  • 安德烈谢谢,我试了一下,但没有解决问题。我可能从根本上错过了一些东西。但是支付控制器嵌套在 bill 下,因此路由“/bills/:bill_id/payments/new(.:format)”正在发送 bill_id。付款新操作获取 bill_id 并构建 @bill。如果我删除linked_to 位,一切正常。我已经添加了账单模型,它可能会显示更多细节。
【解决方案2】:

以下解决了我的问题。

<td>
  <%= link_to "Edit", edit_bill_payment_path(@bill, id: "#{past_payment.id}"), method: :patch %>
</td>
<td>
  <%= link_to "Delete", bill_payment_path(@bill, id: "#{past_payment.id}"), method: :delete, data: { confirm: "Are you sure?" } %>
</td>

我不确定这是否是最佳做法,或者为什么使用 past_payment 对象不起作用。我认为需要做更多的研究。

感谢回复的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 2011-07-09
    • 2020-07-18
    相关资源
    最近更新 更多