【问题标题】:Rails: Form help -- supplying method with argumentRails:表单帮助——提供带参数的方法
【发布时间】:2015-10-11 09:08:26
【问题描述】:

我对 Rails 比较陌生,并尝试编写一个小型贷款应用程序,用户可以在其中向某人贷款,并且该应用程序可以跟踪余额等。我正在向贷款模型添加一个处理付款的功能,并拥有走到这一步(提请注意make_payment(value) 部分:

loan.rb

class Loan < ActiveRecord::Base
  belongs_to :lender, :class_name => 'User'
  belongs_to :borrower, :class_name => 'User'
  has_many :payments

  default_scope -> { order(created_at: :desc) }

  validates :amount, presence: true
  validates :lender, presence: true
  validates :borrower, presence: true

  def make_payment(value)
    remainder = amount - value
    update_attribute(:amount, remainder)
    return remainder
  end
end

我可以使用它从原始贷款金额中正确扣除一个值,但我似乎无法使用视图和表单使其工作。目前我的看法如下:

app/views/loans/show.html.erb

<p id="notice"><%= notice %></p>

<div class="row">
  <div class="col-md-2">
    <ul>
      <li><strong>Lender</strong>: <%= @loan.lender.username %></li>
      <li><strong>Borrower</strong>: <%= @loan.borrower.username %></li>
      <li><strong>Amount Remaining</strong>: <%= @loan.amount %></li>
    </ul>
    <section>
      <div class="col-md-6 col-md-offset-3">
        <%= form_for @loan do |f| %>

          <%= f.label :make_payment %>  <!--confusion -->
          <%= f.number_field :value, class: 'form-control' %>  <!--confusion -->

          <%= f.submit "Submit Payment", class: "btn btn-primary" %>
        <% end %>
      </div>
    </section>
  </div>
</div>

<%= link_to 'Edit', edit_loan_path(@loan) %> |
<%= link_to 'Back', loans_path %>

当我尝试访问该页面时,我收到一个错误wrong number of arguments (0 for 1),这完全有道理,但我希望表单中提交的值是函数make_payment(value) 的参数(值)。我应该使用form_for @loan.make_payment do |f| 还是完全使用其他东西?我确定这是一个简单的解决方法,但我似乎无法找到我正在寻找的答案。

【问题讨论】:

  • 在哪一行抛出错误?粘贴完整的错误日志
  • 您添加的表单。该表单应该用于付款对象。在贷款控制器显示操作中,您应该初始化付款对象。因此提交表单将带您到付款控制器创建操作,您将使用他输入的金额创建付款。该付款属于贷款。 number_field 应该具有 payment 属性,那么您应该在付款模型中具有 after_create 回调,您应该在其中更新贷款金额,这与您目前在贷款付款方式中所做的事情相同。它将使用待处理的更新贷款金额
  • 它在第 12 行抛出错误def make_payment(value)

标签: ruby-on-rails forms model-view-controller arguments models


【解决方案1】:

一个不错的 RESTful 解决方案可能如下所示:

resources :loans, shallow: :true do
  resources :payments, only: :create
end

class PaymentsController < ApplicationController

  # POST /loans/:loan_id/payments
  def create
    @loan = Loan.find(params[:loan_id])
    @loan.make_payment(payment)
    if @load.save
      redirect_to @loan, notice: "Payment successful"
    else
      redirect_to @loan, alert: "Payment count not be processed"
    end 
  end

  private 

  def payment
    require(:loan).require(:payment)[:payment]
  end
end 

然后您的表单将如下所示:

<%= form_for @loan, url: loan_payments_path(loan: @loan), method: :post do |f| %>
  <%= f.label :payment %>
  <%= f.number_field :payment, class: 'form-control' %>
  <%= f.submit "Submit Payment", class: "btn btn-primary" %>
<% end %>

【讨论】:

  • 在上一篇文章中,有人告诉我没有必要制作单独的控制器,我所需要的只是贷款模型中的一个方法。不是这样吗?
  • unnecessary 是错误的词 - 有很多方法可以解决此任务。这是一种采用宁静的方法并将付款视为实际资源的方法。很可能将某些东西混入您的 LoansController#update 方法中,但这不是我要解决的方法。简单实际上更多的是让零件只做一项工作,而不是让几个零件做所有事情。
  • 太棒了!我想我应该学会以正确的方式去做。即使在rake routes 中显示为/loans/:loan_id/payments(.:format),它似乎也找不到付款路径
  • 另外,在你的回复中你写了routes :loans, shallow: :true do routes :payments, only: :create end你是不是要写resources而不是routes
  • 是的,这两个地方都应该是resources@Jeremy。 Rails 指南可以在here 找到。
猜你喜欢
  • 2020-07-27
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多