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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33727431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:18:18  来源:igfitidea点击:

How to add a virtual attribute to a model in Ruby on Rails?

ruby-on-railsrubyruby-on-rails-4activeadmin

提问by moorara

I'm working on a RubyonRails/ActiveAdmin application. My RoR version is 4.2.5 and AA version is 1.0.0. I have a model Messageas follows.

我正在开发 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

As you see, I want to have a read-only attribute palindromewhich only depends on the contentof message. I want this attribute to be treated exactly like a normal attribute. By normal, I mean when I retrieve messages via rails consoleor request jsonformat of messages, I want to see a palindromeattribute in the list. I would also like to have a filter for message by this attribute.

如您所见,我想要一个只读属性palindrome,该属性仅取决于content消息。我希望这个属性被完全像一个普通属性一样对待。通常,我的意思是当我通过rails console或请求json消息格式检索消息时,我想palindrome在列表中看到一个属性。我还想通过此属性过滤消息。

I'm not sure how could I achieve this.

我不知道我怎么能做到这一点。

采纳答案by K M Rakibul Islam

In your model, you can write attribute accessors (reader/writer) for your virtual attribute palindromeattribute this way:

在您的模型中,您可以通过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

And, as you are using Rails 4, you have to whitelist palindromeattribute like any other model attribute in your strong param definition inside your controller in order to able to mass assign the value of palindrome. Something like this:

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

# your_controller.rb
private

def your_model_params
  params.require(:message).permit(:palindrome)
end

Take a look at this RailsCast on Virtual Attributes. Although, it's a bit old, but would be useful for concepts.

看看这个RailsCast on Virtual Attributes。虽然它有点旧,但对概念很有用。

Note:

笔记:

A virtual attribute will not show up in the param list automatically. But, you should be able to access it via Rails console like this: Message.new.palindrome. Also, you can expose this virtual attribute in your JSON API, for example if you are using Active Model Serializer, you can have: attribute palindromein your MessageSerializerand then palindromewill be exposed to the JSON API.

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

回答by Brent Eicher

Ruby actually lets you create virtual attributes this way, which keeps you from having to manually create getter and setter methods:

Ruby 实际上允许您以这种方式创建虚拟属性,这样您就不必手动创建 getter 和 setter 方法:

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

You can also pass multiple arguments too:

您也可以传递多个参数:

attr_accessor :palindrome, :foo, :bar

The documentation for itisn't the greatest.

它的文档并不是最好的。