2014-11-23 2 views
0

Я борюсь с этим, похоже, он должен быть простым - я просто не понимаю, почему это не сработает.link_to с вложенными маршрутами в цикле

У меня есть следующий цикл в представлении платежей, я хочу, чтобы link_to удалял и редактировал. Я передаю объект @bill и объект past_payment.

Я получаю эту ошибку: нет совпадений маршрутов {: action => "edit",: bill_id => 11,: controller => "payments",: id => nil} отсутствуют необходимые ключи: [: id ]

Не могу понять, почему я не могу получить: id от past_payment. Я попытался использовать past_payment.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> 

Controller Код

class PaymentsController < ApplicationController 
    before_action :authenticate_user! 


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

    def edit 
    @bill=Bill.find(params[:bill_id]) 
    @[email protected](: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 

Спасибо за любую помощь.

+0

Можете ли вы дать фрагменты со своего маршрута? – Rubyrider

+0

Пожалуйста, поделитесь кодом контроллера, где инициализируется @bill. – Anand

+0

Является ли эта ошибка выброшенной из 'нового' действия? – blelump

ответ

0

Следующих решить мою проблему.

<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 не сработало. Думаю, нужно сделать немного больше исследований.

Спасибо тем, кто ответил.

1

В действиях вы используете везде, но @bill имеет :id, а не :bill_id. Это проблема. Вы действительно хотите использовать @bill=Bill.find(params[:id]).

Ссылки вы используете: <%= link_to "Pay", new_bill_payment_path(bill) %> дает :id=>nil, потому что нет ни одного объекта счета, но @bill, следовательно, ссылки, скорее всего, должно быть <%= link_to "Pay", new_bill_payment_path(@bill) %>

+0

Спасибо Андрей - новое действие в вызывается из: '<% = link_to" Pay ", new_bill_payment_path (bill)%>' это маршрут проходит bill_id – Smithy

+0

он должен быть '<% = link_to" Pay ", new_bill_payment_path (@bill)%>' then –

+0

Andrey спасибо, я дал это, и это не устранило проблему. Возможно, я вообще что-то пропустил, но контроллер платежей вложен в вексель, так что маршрут /bills/:bill_id/payments/new(.:format) отправляет bill_id. Платежи нового действия забирают bill_id и строят @bill. если я удалю ссылку ed_to бит все работает отлично. Я добавил модель счета, она может показать более подробную информацию. – Smithy

Смежные вопросы