web-dev-qa-db-ja.com

Railsの値でActiveRecordを初期化する方法は?

平易なJavaを使用します:

public User(String name, String email) {
  this.name = name;
  this.email = f(email);
  this.admin = false;
}

ただし、ActiveRecordsでRails(3.2.3)で行う簡単な標準的な方法が見つかりませんでした。

1.初期化のオーバーライド

def initialize(attributes = {}, options = {})
  @name  = attributes[:name]
  @email = f(attributes[:email])
  @admin = false
end

DBからのレコード を作成するときに見落とされる可能性があります

2. after_initializeコールバックを使用する

それをオーバーライドすることにより:

def after_initialize(attributes = {}, options = {})
  ...
end

またはマクロで:

after_initialize : my_own_little_init
def my_own_little_init(attributes = {}, options = {})
  ...
end

ただし、 非推奨の問題 が存在する可能性があります。

いくつかの other リンクがあります in SO ですが、それらは古くなっている可能性があります。


だから、正しい/標準的な方法は何ですか?

25
Asaf

デフォルト値は、すべてのレコードに適用される場合、スキーマで定義する必要があります。そう

def change
  creates_table :posts do |t|
    t.boolean :published, default: false
    t.string :title
    t.text :content
    t.references :author
    t.timestamps
  end
end

ここでは、すべての新しい投稿の公開がfalseになります。オブジェクトレベルでデフォルト値が必要な場合は、Factoryスタイルの実装を使用するのが最適です。

User.build_admin(params)

def self.build_admin(params)
  user = User.new(params)
  user.admin = true
  user
end
17
Jesse Wolgamott

Rails Guidesによると、これを行う最良の方法は after_initialize を使用することです。初期化ではスーパーを宣言する必要があるため、コールバックを使用するのが最善です。 。

15
Mauro George

私が気に入っているソリューションの1つは、スコープを使用することです。

_class User ...
   scope :admins, where(admin: true)
_

次に、両方を行うことができます:User.admins.new(...)を介して管理ステータス(つまりadmin == _true)で新しいユーザーを作成し、同様にすべての管理者を取得します_User.admins_。

いくつかのスコープを作成し、それらのいくつかを作成/検索用のテンプレートとして使用できます。また、_default_scope_を同じ意味で使用できますが、デフォルトで適用される名前はありません。

5
jdoe

これはRails 4。

def initialize(params)
    super
    params[:name] = params[:name] + "xyz" 
    write_attribute(:name, params[:name]) 
    write_attribute(:some_other_field, "stuff")
    write_attribute(:email, params[:email])
    write_attribute(:admin, false)
end
4
Harry Fairbanks

今朝、似たようなものを探していました。データベースにデフォルト値を設定することは明らかに機能しますが、アプリケーションがデータの整合性(つまりデフォルト値?)を処理するというRailsの慣習に違反しているようです。

私はこれを偶然見つけました post 。レコードをすぐにデータベースに保存したくない場合があるため、最善の方法は、write_attribute()の呼び出しでinitializeメソッドを上書きすることだと思います。

def initialize
  super
  write_attribute(name, "John Doe")
  write_attribute(email,  f(email))
  write_attribute(admin, false)
end
4
clekstro