1

我需要一些关于 Ruby on Rails 模型中实例变量和访问器范围的帮助。

这是我的模型的简化(一篇博客文章)。我已经删除了不相关的部分。当然,它有一组验证、关联和自定义方法。

# Table name: articles
#
#  author_url   :string(255)
#  display_date :datetime

class Article < ActiveRecord::Base
  attr_accessible :author_url, :display_date

  # callbacks
  before_create :prepare_properties

  # validations
  VALID_URL_REGEX = /\Ahttps?:\/\/.+/i
  validates :author_url, format: { with: VALID_URL_REGEX,
                                message: " can only use http:// or https:// schemes",
                                     if: Proc.new { author_url.include?("://") } }

  private

    def prepare_properties
      display_date ||= Time.now
      author_url.prepend("http://") unless author_url =~ /\Ahttps?:\/\//i
    end
end

现在:

  • author_url首先使用验证器进行检查,以确保它以 要么 开头,要么http://没有https://
  • 在对象创建时,这应该发生:
    • 如果author_url还没有(有效的)url 方案,http://则默认情况下会在前面添加。
    • 如果作者没有指明显示日期,Time.now则使用。

问题是author_url访问器按预期工作,但display_date它被视为方法范围内的局部变量。如果我将回调与块而不是单独的方法一起使用,也会发生同样的情况。

使其工作的唯一方法是使用self.display_date.

不过,我想知道为什么这只发生在一个属性上而不是另一个属性上。

4

1 回答 1

2

您需要使用self.来调用当前对象的设置器。

self.display_date ||= Time.now

如果没有self.,您是否要创建局部变量或调用 setter 会变得模棱两可,并且 Ruby 默认选择创建局部变量。

不过,我想知道为什么这只发生在一个属性上而不是另一个属性上。

因为你没有设置author_url任何东西;您只是在其上调用一个方法,该方法是使用 getter 获取的。author_url=setter 永远不会被调用。

于 2013-04-30T17:19:30.323 回答