【问题标题】:Return value of the overridden attribute accessor被覆盖的属性访问器的返回值
【发布时间】:2016-08-04 23:48:59
【问题描述】:

我刚刚发现,当我覆盖 Rails 模型的布尔设置器时,返回值的行为异常。

这是一个简单的User 模型,其中is_admin 是一个布尔字段。我想要的很简单:分别将String 'T'、'F' 转换为true、false。

class User < ApplicationRecord
  def is_admin=(value)
    case value
    when 'T'
      super(true)
    when 'F'
      super(false)
    else
      super
    end
  end
end

演员工作正常。 u = User.new; u.is_admin = 'T' 确实将 u.is_admin 设置为 true。然而表达式

u.is_admin = 'T'

返回 'T' 而不是 true。

这很容易通过创建一个全新的 Rails 5 项目并创建一个名为 User 的模型来轻松复制,其中只有一列 is_admin 为 boolean。之后,像我一样覆盖:is_admin,你会看到我看到的。

对奇怪的返回值有什么想法吗?谢谢!

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    赋值运算符总是返回右手边的值。就那么简单。观察:

    class Foo
      def bar=(val)
        @bar = val.to_s # => "1234"
      end
    end
    
    f = Foo.new
    f.bar = 1234 # => 1234
    

    【讨论】:

    • 是的,这就是我所相信的。但就我而言,这不是真的。不覆盖setter的返回值是正常的。但不是在这里调用 super 的覆盖版本。重现错误并不难。您可以关注我在问题中留下的内容。
    • @Xenofex:“没有覆盖”您正在分配布尔值,对吗?它返回布尔值,因为没有强制转换,对吧?那么如何判断这个返回值是来自 setter 还是赋值运算符本身呢?
    • 嗨,@Sergio Tulentsev,在再次阅读您的回答后,我想我明白了您在这里所说的内容。即使我的覆盖看起来像 a 方法,它也是不同的 - 它是一个赋值运算符,它总是返回右手值而不是“最后一行”(甚至我给出一个明确的返回值)。感谢您的解释。虽然有关于此的文档或参考资料吗?
    • @Xenofex:粗略的谷歌搜索没有显示官方文档的链接。虽然一定有一个地方:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 2013-01-31
    • 2013-01-19
    相关资源
    最近更新 更多