[解決済み] Railsです。ActiveRecordでデフォルト値を設定するにはどうすればよいですか?
質問
ActiveRecordでデフォルト値を設定するにはどうすればよいですか?
Pratikからの投稿を見ると、醜く複雑なコードの塊が書かれています。 http://m.onkey.org/2007/7/24/how-to-set-default-values-in-your-model
class Item < ActiveRecord::Base
def initialize_with_defaults(attrs = nil, &block)
initialize_without_defaults(attrs) do
setter = lambda { |key, value| self.send("#{key.to_s}=", value) unless
!attrs.nil? && attrs.keys.map(&:to_s).include?(key.to_s) }
setter.call('scheduler_type', 'hotseat')
yield self if block_given?
end
end
alias_method_chain :initialize, :defaults
end
ググってみると、以下のような例がありました。
def initialize
super
self.status = ACTIVE unless self.status
end
そして
def after_initialize
return unless new_record?
self.status = ACTIVE
end
マイグレーションに入れる人も見かけますが、私はむしろモデルコードで定義してほしいです。
ActiveRecordのモデルでフィールドにデフォルト値を設定する正規の方法はありますか?
どのように解決するのですか?
利用できる方法にはそれぞれいくつかの問題がありますが、私は
after_initialize
コールバックは、次のような理由から、この方法が望ましいと思います。
-
default_scope
は新しいモデルのために値を初期化しますが、その後、それはモデルを見つけるためのスコープになります。もし、いくつかの数値を0に初期化したいだけなら、これは ではなく ということです。 - マイグレーションでデフォルトを定義することも一部では有効ですが...。すでに述べたように、これは ない は、Model.new を呼び出しただけでは動作しません。
-
オーバーライド
initialize
を使用することができます。super
! - phusionのようなプラグインを使うのは、ちょっとバカバカしくなってきましたね。これはrubyです。いくつかのデフォルト値を初期化するためだけにプラグインが必要なのでしょうか?
-
オーバーライド
after_initialize
は非推奨 は、Rails 3 の時点では をオーバーライドするとafter_initialize
をrails 3.0.3で使用すると、コンソールに以下のような警告が表示されます。
DEPRECATION WARNING: Base#after_initialize は非推奨です。代わりに Base.after_initialize :メソッドを使用してください。(/Users/me/myapp/app/models/my_model:15 から呼び出されます)
したがって、私は
after_initialize
コールバックを使用することで、デフォルトの属性を使用することができます。
に加えて
のように、アソシエーションにデフォルトを設定することができます。
class Person < ActiveRecord::Base
has_one :address
after_initialize :init
def init
self.number ||= 0.0 #will set the default value only if it's nil
self.address ||= build_address #let's you set a default association
end
end
これで たった一つ を探し、モデルの初期化を行います。誰かがもっと良い方法を思いつくまで、私はこの方法を使っています。
注意事項
-
ブーリアンフィールドの場合、以下のようにします。
self.bool_field = true if self.bool_field.nil?
詳しくは、この回答に対するPaul Russellのコメントをご覧ください。
-
モデルのカラムのサブセットのみを選択する場合 (たとえば
select
のようなクエリでPerson.select(:firstname, :lastname).all
) を取得することになります。MissingAttributeError
もしinit
メソッドに含まれていないカラムにアクセスします。select
節があります。この場合、次のようにガードすることができます。self.number ||= 0.0 if self.has_attribute? :number
そして、booleanカラムの場合...
self.bool_field = true if (self.has_attribute? :bool_value) && self.bool_field.nil?
また、Rails 3.2以前は構文が異なることに注意してください (以下のCliff Darlingのコメントを参照)。
関連
-
[解決済み] Railsマイグレーションを利用してカラムをドロップする方法
-
[解決済み] Ruby on Railsのマイグレーションでデータベースのカラムの名前を変更するにはどうすればよいですか?
-
[解決済み] Ruby on Railsで現在の絶対URLを取得するにはどうすればよいですか?
-
[解決済み] Rails 4で懸念事項を使用する方法
-
[解決済み] Ruby on RailsのActiveRecordのマイグレーションで、長すぎるインデックス名を処理するには?
-
[解決済み] ActiveRecordオブジェクトを削除するにはどうしたらいいですか?
-
[解決済み】RailsでActiveRecordモデルとそのテーブルの名前を変更するマイグレーションはどのように記述するのですか?
-
[解決済み】ActiveRecord/RailsでNOT INクエリを表現する方法とは?
-
[解決済み】Rails ActiveRecordの日付の間
-
[解決済み] ActiveRecord::Baseを拡張するRails
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Bundler: コマンドが見つからない
-
[解決済み】コントローラでJSONをレンダリングする
-
[解決済み] nil:NilClass の未定義メソッド `each'... なぜでしょうか?
-
[解決済み] Ruby on Railsのランナー
-
[解決済み] rails erb フォームヘルパー options_for_select :selected
-
[解決済み] Railsはsaveでモデル内の検証をスキップしますか?
-
[解決済み] ルビーオンレール モデルから明確な値を選択する
-
[解決済み] rails/rubyでgroup_byを使用する。
-
[解決済み] Rails 4で、以前のバージョンのRailsでattr_accessibleを使用していた状況に遭遇した場合、Forbidden Attributes Errorが発生する。
-
[解決済み】Rails: Railsのactiverecordのモデルで属性のデフォルト値を作成するにはどうすればよいですか?[重複している]。