既存のモデルに、永続化する必要のない、またはデータベース列にマップする必要のない属性を追加したいと思います。そのようなことを指定するための解決策はありますか?
5 に答える
もちろん、古き良きルビーを使用してattr_accessor
ください。モデル内:
attr_accessor :foo, :bar
次のことができるようになります。
object.foo = 'baz'
object.foo #=> 'baz'
同じ問題が発生していましたが、モデルをブートストラップする必要があったため、to_jsonが呼び出された後も属性を保持する必要がありました。このためにもう1つ行う必要があります。
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
メソッドで使用したりできます。
DBテーブルに一致する列が含まれている場合、既存の列のSQLとの間の変換にも影響を与えるため、DBテーブルは永続化されます。attribute
参照:https ://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html#method-i-attribute
私の場合、左結合を使用してカスタム属性を設定したいと思いました。何も追加しなくても機能しますが、新しいオブジェクトに属性を設定できるようにしたいのですが、もちろん存在しません。追加すると、常に。の後にattr_accessor
戻ります。これが私が最終的に得たアプローチであり、新しいオブジェクトを設定し、左結合から取得するために機能します。nil
select
after_initialize do
self.foo = nil unless @attributes.key?("foo")
end
def foo
@attributes["foo"]
end
def foo=(value)
@attributes["foo"] = value
end