0

我试图了解这两种在 Rails 4 中分配虚拟属性的方法之间的区别。其中一种导致“堆栈级别太深”,其中一种工作正常。我试图通过解析文本字段并用逗号分割它来创建一个标签字段来使用新的 ActiveRecord 数组字段。工作代码如下:

class Post < ActiveRecord::Base
  def tags=(s)
    self[:tags] = s.split(/,\s+/)
  end
end

但是,当我将其更改为通过分配给类变量来分配此模型中的标记字段时,会导致“堆栈级别太深”。

class Post < ActiveRecord::Base
  def tags=(s)
    self.tags = s.split(/,\s+/)
  end
end

有人可以解释为什么这会发生在我身上吗?似乎 usingself.tags会导致此虚拟属性一直运行,直到堆栈爆炸为止。ActiveRecord 的哪一部分导致了这种情况?

4

1 回答 1

2

stack level too deep错误与rails无关。任何基本的 Ruby 类都会这样做:

class Post
  def tags=(s)
    self.tags = s
  end
end

> Post.new.tags = "a,b,c"
SystemStackError: stack level too deep     

调用self.tags =只会tags=(s)一遍又一遍地在同一个对象上重新执行。在您的第一个示例中,您通过 直接设置属性self[:tags] =,根本不会重新执行tags=(s)。我会假设 ActiveRecord 的过度简化是它对模型的所有字段执行类似于您的第一个示例的操作。

于 2013-07-15T13:13:19.783 回答