1

我有一个这样的模型:

class Transaction < ActiveRecord::Base
  def amount
    self[:amount].abs
  end

  def transaction_type
    read_attribute(:amount) > 0 ? :credit : :debit
  end

  def transaction_type=(type)
    if type == :credit || type == 'credit'
      self[:amount] = amount.abs
    elsif type == :debit || type == 'debit'
      self[:amount] = amount.abs * -1
    else
      raise ArgumentError.new 'Type must be credit or debit'
    end
  end
end

因为我希望我的金额列在呈现时始终为正数。问题显然是视图从来没有调用过这个方法:

<% form_for @transaction do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label 'Where?' %><br />
    <%= f.text_field :target %>
  </p>
  <p>
    <%= f.label 'What?' %><br />
    <%= f.text_field :memo %>
  </p>
  <p>
    <%= f.label 'How much?' %><br />
    <%= f.text_field :amount %>
  </p>
  <p>
    <%= f.radio_button :transaction_type, 'debit' %>
    <%= f.label :transaction_type_debit, 'Debit' %>
    <%= f.radio_button :transaction_type, 'credit' %>
    <%= f.label :transaction_type_credit, 'Credit' %>
  </p>
  <p><%= f.submit "Submit" %></p>
<% end %>

难道我做错了什么?还是有更好的方法来做到这一点?

编辑:添加了我的 transaction_type 访问器方法,这更好地解释了为什么我不在数据库中将金额存储为仅正数。

4

1 回答 1

2

几年前我也遇到过类似的问题。鉴于所涉及的时间,如果我错了,请原谅。

据我所知,表单助手使用*_before_type_cast访问器方法。考虑将您的方法重命名为amount_before_type_cast. 这里有一些关于“问题”的更多信息。

但是,如果您只希望在视图中将数字设为绝对值,但仍希望在模型中以通常的方式使用该数字,那么这完全是错误的方法,您应该“清理”数据以用于以不同的方式查看视图(即,在控制器中的助手,或在模型上具有全新的非基于数据的自定义属性)。

于 2009-05-23T00:52:59.453 回答