繁体   English   中英

Ruby on Rails与类变量混淆

[英]Ruby on Rails and class variable confusion

我在Rails中有一个具有枚举属性“ status”的模型。 我想要一个公共和私人身份的概念,例如:

class Something < ActiveRecord::Base
  @public_statuses = [:open, :closed, :current]
  @private_statuses = [:deleted]

  enum status: @public_statuses + @private_statuses
end

这样我就可以在视图中执行以下操作:

<select>

<% Something.public_statuses.each do |status| %>
    <option value="<%= status %>"><%= status.humanize %></option>
<% end %>

</select>

这样,我就不会向最终用户公开私有状态。

不幸的是,我不太了解Ruby类,无论我是否执行@public_statuses,@@ public_statuses,public_statuses = [...]等,都无法使它正常工作。我熟悉Java和其他OO语言,但是不要在这里在Ruby中做什么。

什么是正确的方法?

您可以将变量像Class方法一样对待,并将不需要访问的变量定义为private(在Ruby中并非绝对如此)。 喜欢:

    def self.public_statuses
        [:open, :closed, :current]
    end

    def self.private_statuses
        [:deleted]
    end

    private_class_method :private_statuses

但是,如果您真的要使用变量(在这种情况下为常量),则它非常相似:

PUBLIC_STATUSES = [:open, :closed, :current]
PRIVATE_STATUSES = [:deleted]
private_constant :PRIVATE_STATUSES

因此,您可以使用它:

puts Something::PUBLIC_STATUSES
=> [:open, :closed, :current]
puts Something::PRIVATE_STATUSES
NameError: private constant Client::PRIVATE_STATUSES referenced

您所做的是定义了两个实例变量,而不是类变量,因此无法以Foo.instance_variable方式访问它们。 您需要Foo实例才能访问它们。 因此,您可以将每个块的视图替换为:

<% Something.new.public_statuses.each do |status| %>
  <option value="<%= status %>"><%= status.humanize %></option>
<% end %>

在这里,您实例化Something然后在该实例上调用pubic_statuses.each 因此,这将为您工作。

但是,如果要将它们用作类变量,则需要在模型类中添加类访问器方法:

class Something < ActiveRecord::Base
  @@public_statuses = [:open, :closed, :current]
  @private_statuses = [:deleted]

  enum status: public_statuses + @private_statuses


  def self.public_statuses
    @@public_statuses
  end
end

使用Rails时,还可以定义cattr_reader :public_statuses而不是上面代码中定义的getter方法。 通过这些添加类方法的选项,您无需更改视图。

另一种选择是使它们成为常数:

class Something < ActiveRecord::Base
  PUBLIC_STATUSES = [:open, :closed, :current]
  PRIVATE_STATUSES = [:deleted]

  enum status: PUBLIC_STATUSES + PRIVATE_STATUSES
end

然后在您看来:

<% Something::PUBLIC_STATUSES.each do |status| %>

暂无
暂无

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

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