27

プレーン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

ただし、非推奨の問題がいくつかある可能性があります。

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


では、使用する正しい/標準的な方法は何ですか?

4

5 に答える 5

20

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

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
于 2012-05-08T20:11:35.473 に答える
16

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

于 2013-04-07T13:50:15.770 に答える
5

私が気に入っている解決策の 1 つは、スコープを使用することです。

class User ...
   scope :admins, where(admin: true)

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

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

于 2012-05-08T19:49:40.093 に答える
4

これは 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
于 2016-08-08T00:41:49.120 に答える
4

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

この投稿に出くわしました。レコードをすぐにデータベースに保存したくない場合があるため、初期化メソッドを への呼び出しで上書きするのが最善の方法だと思いますwrite_attribute()

def initialize
  super
  write_attribute(name, "John Doe")
  write_attribute(email,  f(email))
  write_attribute(admin, false)
end
于 2012-10-13T08:13:58.213 に答える