代码之家  ›  专栏  ›  技术社区  ›  Mark A. Nicolosi

Rails中的视图不调用重写的属性访问器

  •  1
  • Mark A. Nicolosi  · 技术社区  · 17 年前

    我有一个这样的模型:

    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 %>
    

    我做错什么了吗?还是有更好的方法?

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

    1 回复  |  直到 17 年前
        1
  •  2
  •   Peter Cooper    17 年前

    几年前我也有类似的问题。考虑到涉及的时间,如果我错了,请原谅。

    据我回忆,表单助手使用 *_before_type_cast amount_before_type_cast . 还有关于“问题”的更多信息 here .

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