44

我想向现有模型添加一些不需要持久化的属性,甚至不需要映射到数据库列。有没有解决方案来指定这样的事情?

4

5 回答 5

55

当然使用好的旧红宝石attr_accessor。在您的模型中:

attr_accessor :foo, :bar

您将能够:

object.foo = 'baz'
object.foo #=> 'baz'
于 2012-08-16T12:49:16.650 回答
29

我遇到了同样的问题,但我需要引导模型,因此在调用 to_json 后属性必须保持不变。你需要为此做一件额外的事情。

正如 apneadiving 所说,最简单的开始方法是转到您的模型并添加:

attr_accessor :foo

然后你可以分配你想要的属性。但是要使属性保持不变,您需要更改属性方法。在您的模型文件中添加此方法:

def attributes
  super.merge('foo' => self.foo)
end
于 2013-12-06T06:07:30.933 回答
6

如果有人想知道如何将其渲染到视图,请使用 render 方法的方法参数,如下所示:

render json: {results: results}, methods: [:my_attribute]

请注意,这仅在您在模型上设置 attr_accessor 并在控制器操作中设置属性时才有效,如所选答案所述。

于 2016-01-20T16:53:59.280 回答
4

从 Rails 5.0 开始,您可以使用attribute

class StoreListing < ActiveRecord::Base
  attribute :non_persisted
  attribute :non_persisted_complex, :integer, default: -1
end

属性将attribute像被持久化的属性一样创建,即您可以定义类型和其他选项,将其与create方法一起使用等。

如果您的数据库表包含匹配列,它将被持久化,因为attribute它也用于影响现有列与 SQL 之间的转换。

见:https ://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html#method-i-attribute

于 2020-01-10T15:41:29.797 回答
1

就我而言,我想使用左连接来填充自定义属性。如果我不添加任何东西,它就可以工作,但我也希望能够在新对象上设置属性,当然它不存在。如果我添加attr_accessor,那么它总是nil在 a 之后返回select。这是我最终采用的方法,可用于设置新对象并从左连接中检索。

after_initialize do
  self.foo = nil unless @attributes.key?("foo")
end

def foo
  @attributes["foo"]
end

def foo=(value)
  @attributes["foo"] = value
end
于 2014-10-28T13:01:09.890 回答