[英]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.