简体   繁体   English

Ruby On Rails-模型的属性和访问器范围

[英]Ruby On Rails - Model's properties and accessors scope

I need some help with the scope of instance variables and accessors in a Ruby on Rails model. 我需要一些有关Ruby on Rails模型中实例变量和访问器范围的帮助。

Here is a simplification of my model (a blog article). 这是我的模型的简化(博客文章)。 I've removed the irrelevant parts. 我已经删除了不相关的部分。 Of course it has a set of validations, associations and custom methods. 当然,它具有一组验证,关联和自定义方法。

# 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

Now: 现在:

  • author_url is first checked with a validator that ensures that it begins with either http:// , https:// or nothing. 首先使用验证器检查author_url ,以确保其以http://https://或任何开头。
  • on object creation, this should happen: 在对象创建时,应该发生以下情况:
    • if author_url doesn't already have a (valid) url scheme, http:// is prepended by default. 如果author_url尚未具有(有效的)URL方案,则默认情况下会以http://开头。
    • If the author has not indicated a display_date, Time.now is used. 如果作者未指定display_date,则使用Time.now

The problem is that the author_url accessor works as expected, but the display_date one is treated as a local variable scoped within the method. 问题是author_url访问器可以按预期工作,但是display_date一个被视为方法中范围内的局部变量。 The same happens if I use the callback with a block rather than a separate method. 如果我将回调与块而不是单独的方法一起使用,也会发生同样的情况。

The only way to make it work, is to use self.display_date . 使其起作用的唯一方法是使用self.display_date

Still, I'm wondering why this happens for just one property and not the other. 不过,我想知道为什么只有一个属性而不是另一个属性会发生这种情况。

You need to use self. 您需要使用self. to call setters for the current object. 调用当前对象的设置器。

self.display_date ||= Time.now

Without self. 没有self. , it becomes ambiguous as to whether you want to create a local variable or call the setter, and Ruby chooses creating local variable by default. ,对于要创建局部变量还是调用setter来说,这是模棱两可的,并且Ruby会默认选择创建局部变量。

Still, I'm wondering why this happens for just one property and not the other. 不过,我想知道为什么只有一个属性而不是另一个属性会发生这种情况。

Because you're not setting author_url to anything; 因为您没有将author_url设置为任何值; you're just calling a method on it, which is fetched using the getter. 您只是在上面调用一个方法,该方法是使用getter获取的。 The author_url= setter is never called. 永远不会调用author_url= setter。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM