我有一个这样的模型:
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访问器方法,更好地解释了为什么我不将数据存储在数据库中只是一个正数。
答案 0 :(得分:2)
几年前我遇到过类似的问题。如果有时间,请原谅我,如果我错了。
据我所知,表单助手使用*_before_type_cast
访问器方法。考虑将您的方法重命名为amount_before_type_cast
。有关“问题”here的更多信息。
但是,如果您只想让视图中的数字绝对,但仍希望在模型中以通常的方式使用该数字,那么这完全是错误的方法,您应该“清理”您的数据以不同的方式在视图中使用(即帮助程序,在控制器中,或在模型上使用全新的非数据库自定义属性)。