在Rails中查看不会调用重写的属性访问器

时间:2009-05-23 00:38:53

标签: ruby-on-rails ruby erb

我有一个这样的模型:

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访问器方法,更好地解释了为什么我不将数据存储在数据库中只是一个正数。

1 个答案:

答案 0 :(得分:2)

几年前我遇到过类似的问题。如果有时间,请原谅我,如果我错了。

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

但是,如果您只想让视图中的数字绝对,但仍希望在模型中以通常的方式使用该数字,那么这完全是错误的方法,您应该“清理”您的数据以不同的方式在视图中使用(即帮助程序,在控制器中,或在模型上使用全新的非数据库自定义属性)。