如何在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属性编写属性访问器(读取器/写入器):

 # 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 。 虽然,它有点旧,但对概念有用。

注意:

虚拟属性不会自动显示在参数列表中。 但是,您应该能够通过Rails控制台访问它,如下所示: Message.new.palindrome 。 此外,您可以在JSON API中公开此虚拟属性,例如,如果您使用的是Active Model Serializer ,则可以在MessageSerializer中使用: attribute palindrome ,然后将palindrome暴露给JSON API。

Rails实际上让你以这种方式创建虚拟属性,这使你不必手动创建getter和setter方法:

 attr_reader :palindrome #getter attr_writer :palindrome #setter attr_accessor :palindrome #both 

您也可以传递多个参数:

 attr_accessor :palindrome, :foo, :bar