如何在 Rails Ruby 中为模型添加虚拟属性?
How to add a virtual attribute to a model in Ruby on Rails?
我正在开发 RubyonRails/ActiveAdmin 应用程序。我的RoR版本是4.2.5,AA版本是1.0.0。我有一个模型 Message
如下。
class Message < ActiveRecord::Base
belongs_to :user
validates :user, :content, presence: true
def palindrome
# return true/false
end
end
如您所见,我想要一个只读属性palindrome
,它只依赖于消息的content
。我希望将此属性完全视为普通属性。通常,我的意思是当我通过 rails console
检索消息或请求 json
格式的消息时,我希望在列表中看到 palindrome
属性。我还想通过此属性过滤消息。
我不确定我怎样才能做到这一点。
在您的模型中,您可以通过这种方式为虚拟属性 palindrome
属性编写属性访问器 (reader/writer):
# attr_reader
def palindrome
self[:palindrome]
end
# attr_writer
def palindrome=(val)
self[:palindrome] = val
end
# virtual attribute
def palindrome
#return true/false
end
并且,当您使用 Rails 4 时,您必须像控制器内的强参数定义中的任何其他模型属性一样将 palindrome
属性列入白名单,以便能够批量分配值palindrome
个。像这样:
# your_controller.rb
private
def your_model_params
params.require(:message).permit(:palindrome)
end
看看这个RailsCast on Virtual Attributes。虽然有点旧,但对概念很有用。
注:
虚拟属性不会自动显示在参数列表中。但是,您应该能够像这样通过 Rails 控制台访问它:Message.new.palindrome
。此外,您可以在 JSON API 中公开此虚拟属性,例如,如果您使用 Active Model Serializer,您可以在 MessageSerializer
中包含:attribute palindrome
和然后 palindrome
将暴露给 JSON API.
Ruby 实际上允许您以这种方式创建虚拟属性,这使您不必手动创建 getter 和 setter 方法:
attr_reader :palindrome #getter
attr_writer :palindrome #setter
attr_accessor :palindrome #both
您也可以传递多个参数:
attr_accessor :palindrome, :foo, :bar
documentation for it 不是最好的。
从Rails 5开始你也可以像这样设置虚拟属性:
attribute :palindrome, :boolean
它会自动将属性转换为指定的类型,这在值来自表单时很有用。 This GoRails video shows some really good examples of both using the attr_accessor
and the attribute
approach. The documentation 还包括一些示例。
我正在开发 RubyonRails/ActiveAdmin 应用程序。我的RoR版本是4.2.5,AA版本是1.0.0。我有一个模型 Message
如下。
class Message < ActiveRecord::Base
belongs_to :user
validates :user, :content, presence: true
def palindrome
# return true/false
end
end
如您所见,我想要一个只读属性palindrome
,它只依赖于消息的content
。我希望将此属性完全视为普通属性。通常,我的意思是当我通过 rails console
检索消息或请求 json
格式的消息时,我希望在列表中看到 palindrome
属性。我还想通过此属性过滤消息。
我不确定我怎样才能做到这一点。
在您的模型中,您可以通过这种方式为虚拟属性 palindrome
属性编写属性访问器 (reader/writer):
# attr_reader
def palindrome
self[:palindrome]
end
# attr_writer
def palindrome=(val)
self[:palindrome] = val
end
# virtual attribute
def palindrome
#return true/false
end
并且,当您使用 Rails 4 时,您必须像控制器内的强参数定义中的任何其他模型属性一样将 palindrome
属性列入白名单,以便能够批量分配值palindrome
个。像这样:
# your_controller.rb
private
def your_model_params
params.require(:message).permit(:palindrome)
end
看看这个RailsCast on Virtual Attributes。虽然有点旧,但对概念很有用。
注:
虚拟属性不会自动显示在参数列表中。但是,您应该能够像这样通过 Rails 控制台访问它:Message.new.palindrome
。此外,您可以在 JSON API 中公开此虚拟属性,例如,如果您使用 Active Model Serializer,您可以在 MessageSerializer
中包含:attribute palindrome
和然后 palindrome
将暴露给 JSON API.
Ruby 实际上允许您以这种方式创建虚拟属性,这使您不必手动创建 getter 和 setter 方法:
attr_reader :palindrome #getter
attr_writer :palindrome #setter
attr_accessor :palindrome #both
您也可以传递多个参数:
attr_accessor :palindrome, :foo, :bar
documentation for it 不是最好的。
从Rails 5开始你也可以像这样设置虚拟属性:
attribute :palindrome, :boolean
它会自动将属性转换为指定的类型,这在值来自表单时很有用。 This GoRails video shows some really good examples of both using the attr_accessor
and the attribute
approach. The documentation 还包括一些示例。