如何在Ruby on Rails中为模型添加虚拟属性?

moo*_*ara 22 ruby ruby-on-rails activeadmin ruby-on-rails-4

我正在研究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
Run Code Online (Sandbox Code Playgroud)

如您所见,我想要一个palindrome仅取决于content消息的只读属性.我希望将此属性视为与普通属性完全相同.通常,我的意思是当我通过消息检索消息rails console或请求json消息格式时,我想palindrome在列表中看到一个属性.我还希望通过此属性对消息进行过滤.

我不知道怎么能实现这个目标.

Bre*_*her 24

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

attr_reader   :palindrome #getter
attr_writer   :palindrome #setter
attr_accessor :palindrome #both
Run Code Online (Sandbox Code Playgroud)

您也可以传递多个参数:

attr_accessor :palindrome, :foo, :bar
Run Code Online (Sandbox Code Playgroud)


K M*_*lam 15

在您的模型中,您可以通过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
Run Code Online (Sandbox Code Playgroud)

而且,当您使用Rails 4时,您必须palindrome像控制器内强大的param定义中的任何其他模型属性一样将属性列入白名单,以便能够批量分配值palindrome.像这样的东西:

# your_controller.rb
private

def your_model_params
  params.require(:message).permit(:palindrome)
end
Run Code Online (Sandbox Code Playgroud)

看看这个关于虚拟属性的RailsCast.虽然,它有点旧,但对概念有用.

注意:

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


Ben*_*Ben 11

从 Rails 5 开始,你还可以像这样设置虚拟属性:

attribute :palindrome, :boolean
Run Code Online (Sandbox Code Playgroud)

它会自动将属性转换为指定的类型,这在值来自表单时非常有用。这个 GoRails 视频展示了一些使用attr_accessorattribute方法的非常好的示例。该文档还包括一些示例。