我想向现有模型添加一些不需要持久化的属性,甚至不需要映射到数据库列。有没有解决方案来指定这样的事情?
5 回答
当然使用好的旧红宝石attr_accessor
。在您的模型中:
attr_accessor :foo, :bar
您将能够:
object.foo = 'baz'
object.foo #=> 'baz'
我遇到了同样的问题,但我需要引导模型,因此在调用 to_json 后属性必须保持不变。你需要为此做一件额外的事情。
正如 apneadiving 所说,最简单的开始方法是转到您的模型并添加:
attr_accessor :foo
然后你可以分配你想要的属性。但是要使属性保持不变,您需要更改属性方法。在您的模型文件中添加此方法:
def attributes
super.merge('foo' => self.foo)
end
如果有人想知道如何将其渲染到视图,请使用 render 方法的方法参数,如下所示:
render json: {results: results}, methods: [:my_attribute]
请注意,这仅在您在模型上设置 attr_accessor 并在控制器操作中设置属性时才有效,如所选答案所述。
从 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
就我而言,我想使用左连接来填充自定义属性。如果我不添加任何东西,它就可以工作,但我也希望能够在新对象上设置属性,当然它不存在。如果我添加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