Rails传输表单数据修改错误

时间:2015-08-02 14:15:32

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

我有一个输入转移的表单。此传输存储在数据库中(用于控制器中的事务)。

它大致有效,但现在在保存或进行交易之前,微调输入需要修改。

  • 收件人的姓名需要转换为此用户ID。
  • 该金额有一个两位十进制数输入,应该通过将其乘以一百来修改为美分并使其成为整数。如你所知,银行需要一个整数基础。

我认为这可行:

转移模式

  #transfer.rb
  has_one :sender,
          :class_name => "User", 
          :foreign_key => "sender_id"
  has_one :recipient, 
          :class_name => "User", 
          :foreign_key => "recipient_id"

  validates :sender_id, presence: true
  validates :recipient_id, presence: true
  validates :amount, numericality: {:greater_than => 0}

  before_validation :recipient_name_to_id 
  before_validation :amount_to_cents

  def recipient_name_to_id
    recipient = User.find_by_user_name(self.recipient_id)
    self.recipient_id = recipient.id
  end

  def amount_to_cents
    cents = self.amount
    cents = cents*100
    cents.to_i
    self.amount = cents 
  end

要修改:recipient_id和:从应用程序请求名称和任何数字时从表单中获取的金额。

它不起作用,因为在交易中它无法找到收件人bankaldo。

TransfersController中的NoMethodError #create

未定义的方法`美分'为nil:NilClass

 @account_b.cents += @transfer.amount

其他一切都很好。我仔细检查了一下。

但是添加控制器可能会有所帮助

TransfersController

  def create
    @user = User.find(params[:user_id])
    #transfer
    @transfer = Transfer.new(transfer_params)
    @transfer.sender_id = @user.id

    #transactie tussen accounts
    @account_a = @user.account
    @account_b = Account.find_by_user_id(@transfer.recipient_id)
      if @account_a != @account_b
        if @account_a.cents >= @transfer.amount
          Account.transaction do
              @account_a.cents -= @transfer.amount
              @account_a.save!
              @account_b.cents += @transfer.amount
              @account_b.save!
              @transfer.save!
              flash.notice = "Uw opdracht is verzonden."
          end
        else
          flash.notice = "U beschikt niet over voldoende saldo om uw opdracht te doen slagen."
        end
      else
        flash.notice = "U kunt geen geld overmaken naar uw eigen account."
      end
    redirect_to user_path(@user)
  end

  private
  def transfer_params
    params.require(:transfer).permit(:sender_id, :recipient_id, :amount)
  end

更新

我现在正在使用当前设置(这更聪明,还是不重要?)。

#same transfer.rb model but now with this as non private methods.
def recipient_id=(value)
  user = User.find_by_user_name(value)
  self[:recipient_id] = user.id 
end

def amount=(value)
  cents = value * 100
  cents.to_i
  self[:amount] = cents
end

现在代码给出了:

验证失败:金额不是数字

并且不能@ transfer.save!在控制器中。

更新2

好吧它几乎可以工作。我必须首先通过to_f将值设置为float。然后它工作......直到我再次打开验证(我注释掉了),现在它给出了一个错误,即数量不是整数...我在def中说明了。 Hmprff:S

更新3

现在一切正常。我的方法现在看起来像这样:

  def recipient_id=(value)
    user = User.find_by_user_name(value)
    self[:recipient_id] = user.id 
  end

  def amount=(value)
    cents = value.to_f * 100
    self[:amount] = cents.to_i
  end

关于它的坏处是,使用错误的表单信息,应用程序会给出验证错误屏幕,而我希望它发出通知并将其重定向到显示窗口。

在我在transfermodel中定义的这些方法中找不到flash和redirect方法。

1 个答案:

答案 0 :(得分:0)

@account_b未加载,因为transfer_params[:recipient_id]nil,或者因为该ID不存在Account。您可以考虑切换到Account.where(user_id: @transfer.recipient_id).first!以便它引发异常,或者您需要检查是否@account_b.nil?并处理问题。由于@account_a != nil,您的逻辑会一直持续到您无法访问@account_b.cents

检查您的表单和传入参数以确保存在params[:transfer][:recipient_id],然后验证用户ID是否为Account